/* @internal */
名域 ts {
    变量 nextSymbolId = 1;
    变量 nextNodeId = 1;
    变量 nextMergeId = 1;
    变量 nextFlowId = 1;

    导出 函数 获取节点Id(n: 节点_): 数字 {
        如果 (!n.id) {
            n.id = nextNodeId;
            nextNodeId++;
        }
        返回 n.id;
    }

    导出 函数 getSymbolId(s: 符号_): 数字 {
        如果 (!s.id) {
            s.id = nextSymbolId;
            nextSymbolId++;
        }
        返回 s.id;
    }

    导出 函数 getFlowNodeId(f: 流程节点_): 数字 {
        如果 (!f.id) {
            f.id = nextFlowId;
            nextFlowId++;
        }
        返回 f.id;
    }

    导出 函数 创建类型检查(主机: 类型检查主机_, 生产诊断?: 真假) {

        变量 cancellationToken: 取消令牌_;
        // tslint:disable variable-name
        常量 符号_ = 对象分配器.获取符号构造器();
        常量 类型_ = 对象分配器.获取类型构造器();
        常量 签名_ = 对象分配器.获取签名构造器();
        常量 编译选项 = 主机.获取编译选项()

        变量 typeCount = 0;
        变量 symbolCount = 0;
        变量 symbolInstantiationDepth = 0;        
        // 变量 constraintDepth = 0;
        变量 instantiationDepth = 0;

        常量 未定符号 = 创建未定符号();
        未定符号
        变量 apparentArgumentCount: 数字 | 未定;

        常量 检查: 类型检查_ = {
            获取节点数量: () => sum(主机.获取源文件组(), '符号数量') + symbolCount,
            获取诊断组,
            获取全局诊断
        } 转为 类型检查_

        常量 unionTypes = 创建词典<联合类型_>();
        常量 intersectionTypes = 创建词典<交叉类型_>();
        常量 undefinedProperties = 创建符号表()

        常量 空符号表 = 创建符号表();

        常量 emptyTypeLiteralSymbol = createSymbol(符号标志_.类型字面量_, '@类型');
        emptyTypeLiteralSymbol.成员 = 创建符号表();
        常量 emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, 空符号表, 空符号表);
        常量 emptyGenericType = <泛型类型_><对象类型_>createAnonymousType(未定!, 空符号表, 空符号表);

        emptyGenericType.instantiations = 创建词典<类型引用_>();
        常量 emptyObjectType = createAnonymousType(未定!, 空符号表, 空符号表);

        常量 identityMapper: (类型: 类型_) => 类型_ = 身份;
        常量 解析中符号 = createSymbol(0, '@__解析中__');

        常量 未知符号 = 创建未知符号()
        常量 未知类型 = 创建对象类型(对象标志_.未知_, 未知符号);

        常量 通用符号 = 创建通用符号();
        常量 通用类型 = 创建通用类型(通用符号);
        常量 未定类型 = 创建内置类型(类型标志_.未定_, '未定')

        常量 无值类型 = 创建内置类型(类型标志_.无值_, '无值')

        常量 整数类型_64 = 创建数字类型('整数64', 数字标志_.整数64_);
        常量 整数类型_32 = 创建数字类型('整数32', 数字标志_.整数32_);
        常量 整数类型_16 = 创建数字类型('整数16', 数字标志_.整数16_);
        常量 整数类型_8 = 创建数字类型('整数8', 数字标志_.整数8_);
        常量 整数类型 = 编译选项.架构 === 'amd64' ? 整数类型_64 : 整数类型_32;

        常量 整数类型词典数据 = {
            '整数8': 整数类型_8,
            '整数16': 整数类型_16,
            '整数32': 整数类型_32,
            '整数64': 整数类型_64
        }

        常量 整数类型词典 = 创建词典从模板({
            ...整数类型词典数据
        })
        整数类型词典

        常量 正整数类型_64 = 创建数字类型('正整数64', 数字标志_.正整数64_);
        常量 正整数类型_32 = 创建数字类型('正整数32', 数字标志_.正整数32_);
        常量 正整数类型_16 = 创建数字类型('正整数16', 数字标志_.正整数16_);
        常量 正整数类型_8 = 创建数字类型('正整数8', 数字标志_.正整数8_);
        常量 正整数类型 = 编译选项.架构 === 'amd64' ? 正整数类型_64 : 正整数类型_32;

        常量 正整数类型词典数据 = {
            '正整数8': 正整数类型_8,
            '正整数16': 正整数类型_16,
            '正整数32': 正整数类型_32,
            '正整数64': 正整数类型_64
        }

        常量 正整数类型词典 = 创建词典从模板({
            ...正整数类型词典数据
        })
        正整数类型词典

        常量 小数类型_64 = 创建数字类型('小数64', 数字标志_.小数64_);
        常量 小数类型_32 = 创建数字类型('小数64', 数字标志_.小数32_);
        常量 小数类型 = 编译选项.架构 === 'amd64' ? 小数类型_64 : 小数类型_32;

        常量 小数类型词典数据 = {
            '小数32': 小数类型_32,
            '小数64': 小数类型_64,
        }

        常量 虚数类型_32 = 创建数字类型('虚数32', 数字标志_.虚数32_)
        常量 虚数类型_64 = 创建数字类型('虚数64', 数字标志_.虚数64_)

        常量 虚数类型词典数据 = {
            '虚数32': 虚数类型_32,
            '虚数64': 虚数类型_64
        }
        常量 虚数类型词典 = 创建词典从模板({
            ...虚数类型词典数据
        })
        虚数类型词典

        常量 小数类型词典 = 创建词典从模板({
            ...小数类型词典数据
        })
        小数类型词典

        常量 复数类型_128 = 创建复数类型('复数128', 数字标志_.小数64_, 数字标志_.虚数64_);
        常量 复数类型_64 = 创建复数类型('复数64', 数字标志_.小数32_, 数字标志_.虚数32_);

        常量 复数类型词典数据 = {
            '复数128': 复数类型_128,
            '复数64': 复数类型_64,
        }

        常量 复数类型词典 = 创建词典从模板({
            ...复数类型词典数据
        })
        复数类型词典

        常量 字符类型 = 创建字符类型()

        常量 字节类型 = 创建字节类型();
        常量 无符号指针类型 = 创建无符号指针类型()

        常量 整数词典数据 = {
            ...整数类型词典数据,
            ...正整数类型词典数据
        }
        常量 整数词典 = 创建词典从模板({
            ...整数词典数据
        })
        整数词典

        常量 浮点词典数据 = {
            ...小数类型词典数据,
            ...复数类型词典数据
        }

        常量 浮点词典 = 创建词典从模板({
            ...浮点词典数据
        })
        浮点词典

        常量 数字词典 = 创建词典从模板({
            ...整数词典数据,
            ...浮点词典数据,
            '字符': 字符类型,
            '字节': 字节类型
        })
        数字词典

        常量 文本类型 = 创建内置类型(类型标志_.文本类型_, '文本')
        常量 真类型 = 创建内置类型(类型标志_.真类型_, '真')
        常量 假类型 = 创建内置类型(类型标志_.假类型_, '假')
        常量 真假类型 = 创建真假类型([真类型, 假类型]);

        变量 flowLoopStart = 0;
        变量 flowLoopCount = 0;
        
        常量 任意签名 = createSignature(未定!, 未定!, 未定!, 通用类型, 0, 为假);
        常量 解析中签名 = createSignature(未定!, 未定!, 未定!, 无值类型, 0, 为假);

        常量 anyFunctionType = createAnonymousType(未定!, 空符号表, 空符号表);

        常量 无约束类型 = createAnonymousType(未定!, 空符号表, 空符号表);

        常量 循环自身约束类型 = createAnonymousType(未定!, 空符号表, 空符号表);
        常量 解析中默认类型 = createAnonymousType(未定!, 空符号表, 空符号表);

        /* 
        常量 emitResolver = createResolver();
        常量 nodeBuilder = createNodeBuilder();
        */

        常量 globals = 创建符号表();

        常量 symbolLinks: SymbolLinks[] = [];

        常量 nodeLinks: NodeLinks[] = [];

        常量 解析的目标组: 类型系统条目_[] = [];
        常量 解析的结果组: 真假[] = [];
        常量 解析的属性名称组: 类型系统属性名称_[] = [];

        /*
        变量 suggestionCount = 0;
        常量 maximumSuggestionCount = 10;
        */

        常量 markerSuperType = <类型参数_>创建类型(类型标志_.类型参数_);
        常量 markerSubType = <类型参数_>创建类型(类型标志_.类型参数_);
        markerSubType.约束 = markerSuperType;
        常量 markerOtherType = <类型参数_>创建类型(类型标志_.类型参数_);

        常量 mergedSymbols: 符号_[] = [];

        常量 potentialNewTargetCollisions: 节点_[] = [];
        常量 deferredUnusedIdentifierNodes: 节点_[] = [];

        常量 diagnostics = 创建诊断集合();

        常量 子类型关系 = 创建词典<关系比较结果_>();
        常量 可赋值关系 = 创建词典<关系比较结果_>();
        常量 绝对可以赋值关系 = 创建词典<关系比较结果_>();
        常量 可比较关系 = 创建词典<关系比较结果_>();
        常量 身份关系 = 创建词典<关系比较结果_>();

        类型 类型系统条目_ = 符号_ | 类型_ | 签名_;

        常量 枚举 类型系统属性名称_ {
            类型_,
            解析的基构造类型_,
            声明的类型_,
            解析的返回类型_,
            解析的基约束_,
        }

        常量 枚举 ExpandingFlags {
            None = 0,
            Source = 1,
            Target = 1 << 1,
            Both = Source | Target,
        }

        常量 数字字面量值范围数据 = {
            '正整数': 编译选项.架构 === 'amd64' ? { 最小: 0, 最大: 18446744073709551615 } : { 最小: 0, 最大: 4294967295 },
            '正整数8': { 最小: 0, 最大: 255 },
            '正整数16': { 最小: 0, 最大: 65535 },
            '正整数32': { 最小: 0, 最大: 4294967295 },
            '正整数64': { 最小: 0, 最大: 18446744073709551615 },
            '整数': 编译选项.架构 === 'amd64' ? { 最小: -9223372036854775808, 最大: 9223372036854775807 } : { 最小: -2147483648, 最大: 2147483647 },
            '整数8': { 最小: -128, 最大: 127 },
            '整数16': { 最小: -32768, 最大: 32767 },
            '整数32': { 最小: -2147483648, 最大: 2147483647 },
            '整数64': { 最小: -9223372036854775808, 最大: 9223372036854775807 },
            '小数32': { 最小: -3.4E+38, 最大: 3.4E+38 },
            '小数64': { 最小: 数字_.__最小_有效值__, 最大: 数字_.__最大_有效值__ },
            '字符': { 最小: -2147483648, 最大: 2147483647 },
            '字节': { 最小: -128, 最大: 127 },
            '指针': 编译选项.架构 === 'amd64' ? { 最小: 0, 最大: 18446744073709551615 } : { 最小: 0, 最大: 4294967295 },
        }

        常量 数字字面量值范围 = 创建词典从模板<数值范围_>({
            ...数字字面量值范围数据
        })


        常量 枚举 TypeFacts {
            None = 0,
            EQUndefined = 1 << 1,        // x === 未定
            EQNull = 1 << 2,             // x === null
            EQUndefinedOrNull = 1 << 3,  // x === 未定 / x === null
            NEUndefined = 1 << 4,        // x !== 未定
            NENull = 1 << 5,             // x !== null
            NEUndefinedOrNull = 1 << 6,  // x != 未定 / x != null
            Truthy = 1 << 7,             // x
            Falsy = 1 << 8,              // !x
            All = (1 << 9) - 1,
            // The following members encode facts about particular kinds of types for use in the getTypeFacts function.
            // The presence of a particular fact means that the given test is true for some (and possibly all) values
            // of that 种类 of 类型.
            BaseStringStrictFacts = NEUndefined | NENull | NEUndefinedOrNull,
            BaseStringFacts = BaseStringStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            StringStrictFacts = BaseStringStrictFacts | Truthy | Falsy,
            StringFacts = BaseStringFacts | Truthy,
            EmptyStringStrictFacts = BaseStringStrictFacts | Falsy,
            EmptyStringFacts = BaseStringFacts,
            NonEmptyStringStrictFacts = BaseStringStrictFacts | Truthy,
            NonEmptyStringFacts = BaseStringFacts | Truthy,
            BaseNumberStrictFacts = NEUndefined | NENull | NEUndefinedOrNull,
            BaseNumberFacts = BaseNumberStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            NumberStrictFacts = BaseNumberStrictFacts | Truthy | Falsy,
            NumberFacts = BaseNumberFacts | Truthy,
            ZeroStrictFacts = BaseNumberStrictFacts | Falsy,
            ZeroFacts = BaseNumberFacts,
            NonZeroStrictFacts = BaseNumberStrictFacts | Truthy,
            NonZeroFacts = BaseNumberFacts | Truthy,
            BaseBooleanStrictFacts = NEUndefined | NENull | NEUndefinedOrNull,
            BaseBooleanFacts = BaseBooleanStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            BooleanStrictFacts = BaseBooleanStrictFacts | Truthy | Falsy,
            BooleanFacts = BaseBooleanFacts | Truthy,
            FalseStrictFacts = BaseBooleanStrictFacts | Falsy,
            FalseFacts = BaseBooleanFacts,
            TrueStrictFacts = BaseBooleanStrictFacts | Truthy,
            TrueFacts = BaseBooleanFacts | Truthy,
            SymbolStrictFacts = NEUndefined | NENull | NEUndefinedOrNull | Truthy,
            SymbolFacts = SymbolStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            ObjectStrictFacts = NEUndefined | NENull | NEUndefinedOrNull | Truthy,
            ObjectFacts = ObjectStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            FunctionStrictFacts = NEUndefined | NENull | NEUndefinedOrNull | Truthy,
            FunctionFacts = FunctionStrictFacts | EQUndefined | EQNull | EQUndefinedOrNull | Falsy,
            UndefinedFacts = EQUndefined | EQUndefinedOrNull | NENull | Falsy,
            NullFacts = EQNull | EQUndefinedOrNull | NEUndefined | Falsy,
        }

        常量 枚举 类型包括_ {
            通用_ = 1 << 0,
            Undefined = 1 << 1,
            Null = 1 << 2,
            Never = 1 << 3,
            NonWideningType = 1 << 4,
            String = 1 << 5,
            Number = 1 << 6,
            ESSymbol = 1 << 7,
            LiteralOrUniqueESSymbol = 1 << 8,
            对象类型_ = 1 << 9,
            EmptyObject = 1 << 10,
            联合_ = 1 << 11,
            Wildcard = 1 << 12,
        }

        常量 枚举 检查模式_ {
            正常的_ = 0,                // Normal 类型 checking
            跳过上下文相关_ = 1,  // Skip context sensitive 函数_ expressions
            推理的_ = 2,           // Inferential typing
            上下文的_ = 3,            // Normal 类型 checking informed by a contextual 类型, therefore not cacheable
        }

        常量 枚举 CallbackCheck {
            None,
            Bivariant,
            Strict,
        }

        初始化类型检查();

        返回 检查;


        /*
        // Suggestion diagnostics must have a file. Keyed by source file name.
        常量 suggestionDiagnostics = 创建多维词典<诊断_>();

        函数 addSuggestionDiagnostic(diag: 诊断_): 无值 {
            suggestionDiagnostics.添加(diag.文件!.文件名, { ...diag, 级别: 诊断级别_.建议_ });
        }

        函数 addErrorOrSuggestionDiagnostic(isError: 真假, diag: 诊断_): 无值 {
            如果 (isError) {
                diagnostics.添加(diag);
            }
            否则 {
                addSuggestionDiagnostic(diag);
            }
        }
        */

        函数 error(location: 节点_, message: 诊断信息_, arg0?: 文字 | 数字, arg1?: 文字 | 数字, arg2?: 文字 | 数字, arg3?: 文字 | 数字): 无值 {
            常量 diagnostic = location
                ? 创建诊断从节点(location, message, arg0, arg1, arg2, arg3)
                : 创建编译器诊断(message, arg0!, arg1!, arg2!, arg3!);
            diagnostics.添加(diagnostic);
        }

        函数 createSymbol(标志: 符号标志_, name: 文字, checkFlags?: CheckFlags) {
            symbolCount++;
            常量 符号 = <临时符号_>(新建 符号_(标志 | 符号标志_.临时的_, name));
            符号.checkFlags = checkFlags || 0;
            返回 符号;
        }

        函数 登记合并符号(目标: 符号_, source: 符号_) {
            如果 (!source.合并Id) {
                source.合并Id = nextMergeId;
                nextMergeId++;
            }
            mergedSymbols[source.合并Id] = 目标;
        }

        函数 cloneSymbol(符号: 符号_): 符号_ {
            常量 结果 = createSymbol(符号.标志, 符号.名称);
            结果.声明组 = 符号.声明组 ? 符号.声明组.分切() : [];
            结果.父符号 = 符号.父符号;
            如果 (符号.值声明) 结果.值声明 = 符号.值声明;
            如果 (符号.成员) 结果.成员 = cloneMap(符号.成员);
            如果 (符号.导出表) 结果.导出表 = cloneMap(符号.导出表);
            登记合并符号(结果, 符号);
            返回 结果;
        }

        函数 getExcludedSymbolFlags(标志: 符号标志_): 符号标志_ {
            变量 结果: 符号标志_ = 0;
            如果 (标志 & 符号标志_.变量_) 结果 |= 符号标志_.变量排除_;
            如果 (标志 & 符号标志_.别名_) 结果 |= 符号标志_.别名排除_;
            如果 (标志 & 符号标志_.属性_) 结果 |= 符号标志_.属性排除_;
            如果 (标志 & 符号标志_.函数签名_) 结果 |= 符号标志_.函数签名排除_;
            如果 (标志 & 符号标志_.接口_) 结果 |= 符号标志_.接口排除_;
            如果 (标志 & 符号标志_.结构_) 结果 |= 符号标志_.结构排除_;
            如果 (标志 & 符号标志_.类型别名_) 结果 |= 符号标志_.类型别名排除_;
            如果 (标志 & 符号标志_.类型声明_) 结果 |= 符号标志_.类型声明排除_;
            如果 (标志 & 符号标志_.方法_) 结果 |= 符号标志_.方法排除_;
            如果 (标志 & 符号标志_.方法签名_) 结果 |= 符号标志_.方法签名排除_;
            如果 (标志 & 符号标志_.创建函数签名_) 结果 |= 符号标志_.创建函数排除_;
            如果 (标志 & 符号标志_.初始函数_) 结果 |= 符号标志_.初始函数排除_;
            如果 (标志 & 符号标志_.类型参数_) 结果 |= 符号标志_.类型参数排除_;
            如果 (标志 & 符号标志_.枚举_) 结果 |= 符号标志_.枚举排除_;
            如果 (标志 & 符号标志_.枚举成员_) 结果 |= 符号标志_.枚举成员排除;
            返回 结果;
        }

        函数 mergeSymbol(目标: 符号_, source: 符号_) {
            如果 (!(目标.标志 & getExcludedSymbolFlags(source.标志))) {

                目标.标志 |= source.标志;

                添加范围(目标.声明组, source.声明组);

                如果 (source.成员) {
                    如果 (!目标.成员) 目标.成员 = 创建符号表();
                    mergeSymbolTable(目标.成员, source.成员);
                }

                如果 (source.导出表) {
                    如果 (!目标.导出表) 目标.导出表 = 创建符号表();
                    mergeSymbolTable(目标.导出表, source.导出表);
                }

                如果 (source.方法集合) {
                    如果 (!目标.方法集合) 目标.方法集合 = 创建词典();
                    source.方法集合.循环执行((v, k) => {
                        如果 (!目标.方法集合!.具有(k)) {
                            目标.方法集合!.设置(k, 创建符号表())
                        }
                        mergeSymbolTable(目标.方法集合!.获取(k)!, v)
                    })
                }

                如果 (source.启动符号) {
                    目标.启动符号 = source.启动符号
                }

                添加范围(目标.初始声明组, source.初始声明组)
                source.初始声明组 = 目标.初始声明组
                登记合并符号(目标, source);
            }

            否则 {
                常量 message = 诊断信息_.无法重新声明块范围变量_0

                循环执行(source.声明组!, node => {
                    常量 errorNode = 获取声明名称(node) || node;
                    error(errorNode, message, 'symbolToString(source)');
                });

                循环执行(目标.声明组!, node => {
                    常量 errorNode = 获取声明名称(node) || node;
                    error(errorNode, message, 'symbolToString(source)');
                });
            }
        }
        /*

        函数 combineSymbolTables(first: 符号表_ | 未定, second: 符号表_ | 未定): 符号表_ | 未定 {
            如果 (!first || first.大小 === 0) 返回 second;
            如果 (!second || second.大小 === 0) 返回 first;
            常量 combined = 创建符号表();
            mergeSymbolTable(combined, first);
            mergeSymbolTable(combined, second);
            返回 combined;
        }
        */

        函数 mergeSymbolTable(目标: 符号表_, source: 符号表_) {
            source.循环执行((sourceSymbol, id) => {
                变量 targetSymbol = 目标.获取(id);
                如果 (!targetSymbol) {
                    目标.设置(id, sourceSymbol);
                }
                否则 {
                    如果 (!(targetSymbol.标志 & 符号标志_.临时的_)) {
                        targetSymbol = cloneSymbol(targetSymbol);
                        目标.设置(id, targetSymbol);
                    }
                    mergeSymbol(targetSymbol, sourceSymbol);
                }
            });
        }

        /*
        函数 addToSymbolTable(目标: 符号表_, source: 符号表_, message: 诊断信息_) {
            source.循环执行((sourceSymbol, id) => {
                常量 targetSymbol = 目标.获取(id);
                如果 (targetSymbol) {
                    // Error on redeclarations
                    循环执行(targetSymbol.声明组, addDeclarationDiagnostic(unescapeLeadingUnderscores(id), message));
                }
                否则 {
                    目标.设置(id, sourceSymbol);
                }
            });

            函数 addDeclarationDiagnostic(id: 文字, message: 诊断信息_) {
                返回 (declaration: 声明_) => diagnostics.添加(创建诊断从节点(declaration, message, id));
            }
        }
        */

        函数 getMergedSymbol(符号: 符号_): 符号_ {
            变量 merged: 符号_;
            返回 符号 && 符号.合并Id && (merged = mergedSymbols[符号.合并Id]) ? merged : 符号;
        }

        函数 getSymbolLinks(符号: 符号_): SymbolLinks {
            如果 (符号.标志 & 符号标志_.临时的_) 返回 <临时符号_>符号;
            常量 id = getSymbolId(符号);
            返回 symbolLinks[id] || (symbolLinks[id] = {});
        }

        函数 getNodeLinks(node: 节点_): NodeLinks {
            常量 nodeId = 获取节点Id(node);
            返回 nodeLinks[nodeId] || (nodeLinks[nodeId] = { 标志: 0 });
        }

        函数 获取符号(symbols: 符号表_, name: 文字, meaning: 符号标志_): 符号_ | 未定 {
            如果 (meaning) {
                常量 符号 = symbols.获取(name);
                如果 (符号) {
                    调试_.断言((getCheckFlags(符号) & CheckFlags.Instantiated) === 0, 'Should never get an instantiated 符号 here.');
                    如果 (符号.标志 & meaning) {
                        返回 符号;
                    }
                    如果 (符号.标志 & 符号标志_.别名_) {
                        常量 目标 = resolveAlias(符号);
                        // Unknown 符号 means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors
                        如果 (目标 === 未知符号 || 目标.标志 & meaning) {
                            返回 符号;
                        }
                    }
                }
            }
            // 返回 未定 如果 we can't find a 符号.
        }

        函数 getDeclarationOfAliasSymbol(符号: 符号_): 声明_ | 未定 {
            返回 查找<声明_>(符号.声明组!, 是别名符号声明);
        }

        函数 获取目标从导入从声明(n: 导入从成员_): 符号_ {
            变量 link = getNodeLinks(n)
            如果 (!link.解析的别名符号) {
                变量 导入从声明 = n.父节点 转为 导入从声明_
                变量 源文件 = 获取节点的源文件(n)
                变量 解析的包名 = 源文件.解析的模块!.获取(导入从声明.模块名.文本)!
                变量 首源文件名 = 解析的包名.全部源码文件名![0]
                变量 外部模块源文件 = 主机.获取源文件(首源文件名)
                变量 合并符号 = getMergedSymbol(外部模块源文件.程序集)
                link.解析的别名符号 = 获取符号(合并符号.成员!, n.名称!.文本, (符号标志_.值_ | 符号标志_.类型_)) || 未知符号
            }
            返回 link.解析的别名符号!
        }

        函数 获取目标从导入声明(n: 导入成员_) {
            变量 link = getNodeLinks(n)
            如果 (!link.解析的别名符号) {
                变量 源文件 = 获取节点的源文件(n)
                变量 解析的包名 = 源文件.解析的模块!.获取(n.模块名.文本)!
                变量 首源文件名 = 解析的包名.全部源码文件名![0]
                变量 外部模块源文件 = 主机.获取源文件(首源文件名)
                link.解析的别名符号 = getMergedSymbol(外部模块源文件.程序集)
            }
            返回 link.解析的别名符号!
        }

        函数 getTargetOfAliasDeclaration(n: 声明_): 符号_ | 未定 {
            假如 (n.种类) {
                若是 语法_.导入从成员_:
                    返回 获取目标从导入从声明(<导入从成员_>n);
                若是 语法_.导入成员_:
                    返回 获取目标从导入声明(<导入成员_>n);
            }
        }

        函数 isSelfReferenceLocation(node: 节点_): 真假 {
            假如 (node.种类) {
                若是 语法_.函数声明_:
                若是 语法_.接口声明_:
                若是 语法_.结构声明_:
                若是 语法_.方法声明_:
                    返回 为真;
                默认:
                    返回 为假;
            }
        }

        函数 解析名称(
            位置: 节点_ | 未定,
            名称: 文字,
            意义: 符号标志_,
            名称未发现消息: 诊断信息_ | 未定,
            名称参数: 文字 | 标识符_,
            是使用: 真假,
            排除全局的 = 为假,
            未找到名称建议消息?: 诊断信息_): 符号_ {
            返回 解析名称助手(位置, 名称, 意义, 名称未发现消息!, 名称参数, 是使用, 排除全局的, 获取符号, 未找到名称建议消息);
        }

        函数 解析名称助手(
            位置: 节点_ | 未定,
            名称: 文字,
            意义: 符号标志_,
            名称未发现消息: 诊断信息_,
            名称参数: 文字 | 标识符_,
            是使用: 真假,
            排除全局的: 真假,
            查找: 类为 获取符号,
            未找到名称建议消息?: 诊断信息_): 符号_ {
            常量 起点位置 = 位置; // needed 循环 did-you-mean error reporting, which gathers candidates starting from the original location
            变量 结果: 符号_ | 未定;
            变量 最后位置: 节点_;
            变量 最后自引用位置: 节点_;
            变量 属性包括无效初始化: 节点_;
            常量 错误位置 = 位置;
            起点位置
            名称参数
            未找到名称建议消息
            属性包括无效初始化!
            错误位置
            loop: 判断 (位置) {
                如果 (!是源文件(位置) && 位置.本地组) {
                    /**
                     * 源文件
                     * 方法声明_:
                     * 函数声明_:
                     * 新建函数签名_:
                     * 创建函数签名_:
                     * 方法签名_:
                     * 函数类型_:
                     * 函数签名_:
                     * 启动函数声明_:
                     * 初始函数声明_:
                     * 若是块
                     * 块
                     * 循环
                     * 循环属于 
                     */
                    结果 = 查找(位置.本地组, 名称, 意义)
                    如果 (!结果 && 位置.本地组.具有('@返回值')) {
                        常量 返回值位置 = 位置.本地组.获取('@返回值')!
                        结果 = 查找(返回值位置.成员!, 名称, 意义)
                    }
                    如果 (结果) {
                        变量 useResult = 为真;
                        如果 (是函数族(位置) && 最后位置! && 最后位置 !== (<函数族声明_>位置).主体) {
                            如果 (意义 & 结果.标志 & 符号标志_.类型_) {
                                useResult = 结果.标志 & 符号标志_.类型参数_
                                    // 类型 parameters are visible in parameter list, 返回 类型 and 类型 parameter list
                                    ? 最后位置 === (<普通函数族声明_>位置).类型 ||
                                    最后位置!.种类 === 语法_.参数_ ||
                                    最后位置!.种类 === 语法_.类型参数声明_
                                    // local types not visible outside the function body
                                    : 为假;
                            }
                            如果 (意义 & 符号标志_.值_ && 结果.标志 & 符号标志_.变量_) {
                                useResult = 最后位置!.种类 === 语法_.参数_ || (
                                    最后位置 === (<普通函数族声明_>位置).类型 &&
                                    结果.值声明.种类 === 语法_.参数_);
                            }
                        }
                        如果 (useResult) {
                            跳出 loop;
                        }
                        否则 {
                            结果 = 未定!;
                        }
                    }
                }
                假如 (位置.种类) {
                    若是 语法_.源文件_:
                        结果 = 查找((<源文件_>位置).本地组!, 名称, 意义)!
                        如果 (结果) {
                            跳出 loop;
                        }
                        跳出;
                    若是 语法_.程序声明_:
                        结果 = 查找((<程序声明_>位置).符号.成员!, 名称, 意义)!
                        如果 (结果) {
                            跳出 loop;
                        }
                        跳出;
                    若是 语法_.枚举声明_:
                        结果 = 查找((<程序声明_>位置).符号.成员!, 名称, 意义 & 符号标志_.枚举成员_)!
                        如果 (结果) {
                            跳出 loop;
                        }
                        跳出;
                    若是 语法_.函数表达式_:
                        如果 (意义 & 符号标志_.函数签名_) {
                            // 递归函数调用
                            常量 函数名称 = (<函数表达式_>位置).名称;
                            如果 (函数名称 && 名称 === 函数名称.文本) {
                                结果 = 位置.符号;
                                跳出 loop;
                            }
                        }
                        跳出;
                }
                如果 (isSelfReferenceLocation(位置)) {
                    最后自引用位置 = 位置;
                }
                最后位置 = 位置;
                位置 = 位置.父节点;
            }

            如果 (是使用 && 结果 && 名称未发现消息 && (!最后自引用位置! || 结果 !== 最后自引用位置!.符号)) {
                结果.是被引用的! |= 意义;
            }

            如果 (!结果) {
                如果 (!排除全局的) {
                    结果 = 查找(globals, 名称, 意义);
                }
            }

            如果 (!结果) {
                返回 未定!;
            }

            如果 (名称未发现消息) {

            }

            返回 结果;
        }

        函数 resolveAlias(符号: 符号_): 符号_ {
            调试_.断言((符号.标志 & 符号标志_.别名_) !== 0, 'Should only get Alias here.');
            常量 links = getSymbolLinks(符号);
            如果 (!links.目标) {
                links.目标 = 解析中符号;
                常量 node = getDeclarationOfAliasSymbol(符号)!;
                调试_.断言(!!node);
                常量 目标 = getTargetOfAliasDeclaration(node);
                如果 (links.目标 === 解析中符号) {
                    links.目标 = 目标 || 未知符号;
                }
                否则 {
                    error(node, 诊断信息_.Circular_definition_of_import_alias_0, 'symbolToString(符号)');
                }
            }
            否则 如果 (links.目标 === 解析中符号) {
                links.目标 = 未知符号;
            }
            返回 links.目标!;
        }

        函数 resolveEntityName(name: 实体名或实体名表达式_, 意义: 符号标志_, ignoreErrors?: 真假, 不解析别名?: 真假, location?: 节点_): 符号_ | 未定 {
            如果 (节点是失踪(name)) {
                返回 未定;
            }
            变量 符号: 符号_;
            变量 名称意义 = 符号标志_.程序_ | 意义
            如果 (name.种类 === 语法_.标识符_) {
                如果 (name.文本 === '本体') {
                    意义 |= 符号标志_.属性_
                }
                常量 message = 意义 === 名称意义 ? 诊断信息_.Cannot_find_namespace_0 : 诊断信息_.Cannot_find_name_0;
                符号 = 解析名称(location || name, name.文本, 意义, ignoreErrors ? 未定 : message, name, 为真);
                如果 (!符号) {
                    返回 未定;
                }
            }
            否则 如果 (name.种类 === 语法_.限定名_ || name.种类 === 语法_.属性访问表达式_) {
                常量 left = name.种类 === 语法_.限定名_ ? name.左侧 : name.表达式;
                常量 right = name.种类 === 语法_.限定名_ ? name.右侧 : name.名称;

                变量 namespace = resolveEntityName(left, 名称意义, ignoreErrors, 为假, location);

                如果 (!namespace || 节点是失踪(right)) {
                    返回 未定;
                }
                否则 如果 (namespace === 未知符号) {
                    返回 namespace;
                }
                如果 (namespace.标志 & 符号标志_.程序_) {
                    变量 解析类型 = 获取导出符号表(namespace)!
                    符号 = 解析类型 && 获取符号(解析类型!.成员!, right.文本, 意义)!;
                }
                如果 (!符号! && namespace.名称 === '本体') {
                    变量 结构名称 = 获取接受者名称(<接受者声明_>namespace!.值声明!)!
                    变量 结构符号 = resolveEntityName(结构名称, 符号标志_.类型_)!
                    符号 = 获取符号(结构符号.声明组![0].本地组!, right.文本, 意义)!;
                }
                如果 (!符号!) {
                    如果 (!ignoreErrors) {
                        error(right, 诊断信息_.Namespace_0_has_no_exported_member_1, `getFullyQualifiedName(namespace)`, `declarationNameToString(right)`);
                    }
                    返回 未定;
                }
            }
            否则 {
                调试_.断言不及(name, "Unknown entity name 种类.");
            }
            调试_.断言((getCheckFlags(符号!) & CheckFlags.Instantiated) === 0, "Should never get an instantiated 符号 here.");
            返回 (符号!.标志 & 意义) || 不解析别名 ? 符号! : resolveAlias(符号!);
        }

        函数 获取导出符号表(s: 符号_): 解析类型_ | 未定{
            如果 ((s.标志 & 符号标志_.结构_) || (s.标志 & 符号标志_.程序_)) {
                返回 获取程序获结构符号解析类型(s)
            }
            返回 未定
        }

        函数 获取程序获结构符号解析类型(s: 符号_) {
            返回 resolveStructuredTypeMembers(<结构类型_ | 程序类型_>getDeclaredTypeOfSymbol(getMergedSymbol(s)))
        }

        函数 获取接受者名称(n: 接受者声明_) {
            变量 类型节点 = n.类型
            如果 (是指针类型节点(类型节点)) {
                类型节点 = 类型节点.基础类型
            }
            如果 (是类型引用节点(类型节点)) {
                变量 类型名称 = getTypeReferenceName(类型节点)!
                如果 (类型名称 && 是标识符(类型名称)) {
                    返回 类型名称
                }
            }
            返回 未定
        }

        函数 创建类型(标志: 类型标志_): 类型_ {
            常量 result = 新建 类型_(检查, 标志);
            typeCount++;
            result.id = typeCount;
            返回 result;
        }

        函数 创建内置类型(种类: 类型标志_, 内置类型名称: 文字): 内置类型_ {
            常量 类型 = <内置类型_>创建类型(种类);
            类型.名称 = 内置类型名称;
            返回 类型;
        }

        函数 创建未知符号() {
            变量 符号 = createSymbol(符号标志_.属性_, '@未知');
            符号.声明组 = []
            符号.值声明 = 未定!
            符号.成员 = 空符号表
            返回 符号
        }

        函数 创建未定符号() {
            变量 符号 = createSymbol(符号标志_.属性_, '未定');
            符号.声明组 = []
            符号.值声明 = 未定!
            符号.成员 = 空符号表
            返回 符号
        }

        函数 创建通用符号() {
            变量 符号 = createSymbol(符号标志_.接口_, '通用')
            符号.声明组 = []
            符号.值声明 = 未定!
            符号.成员 = 空符号表
            返回 符号
        }

        函数 创建通用类型(符号: 符号_) {
            返回 (<对象类型_>创建对象类型(对象标志_.接口_, 符号));
        }

        函数 创建字节类型() {
            常量 类型 = (<字节类型_>创建数字类型('字节', 数字标志_.整数8_));
            返回 类型;
        }

        函数 创建字符类型() {
            常量 类型 = (<字节类型_>创建数字类型('字符', 数字标志_.整数32_));
            返回 类型;
        }

        函数 创建无符号指针类型() {
            常量 类型 = (<无符号指针类型_>创建数字类型('指针', 编译选项.架构 === 'amd64' ? 数字标志_.正整数64_ : 数字标志_.正整数32_));
            返回 类型;
        }

        函数 createAnonymousType(符号: 符号_, members: 符号表_, 方法组: 符号表_): 解析类型_ {
            返回 setStructuredTypeMembers(创建对象类型(对象标志_.匿名_, 符号), members, 方法组, 空数组);
        }

        函数 创建数字类型(名称: 文字, 数字标志: 数字标志_) {
            常量 类型 = (<数字类型_>创建内置类型(类型标志_.数字类型_, 名称));
            类型.数字标志 = 数字标志
            返回 类型;
        }

        函数 创建复数类型(名称: 文字, 实数标志: 数字标志_, 虚数标志: 数字标志_) {
            常量 类型 = (<复数类型_>创建数字类型(名称, (虚数标志 !== 数字标志_.虚数64_ && 实数标志 !== 数字标志_.小数64_) ? 数字标志_.复数64_ : 数字标志_.复数128_));
            类型.实数类型 = ((实数标志 & 数字标志_.小数64_) ? 小数类型_64 : 小数类型_32) 转为 小数类型_
            类型.虚数类型 = ((虚数标志 & 数字标志_.虚数64_) ? 虚数类型_64 : 虚数类型_32) 转为 小数类型_
            返回 类型
        }

        函数 创建复合类型(类型: 类型_, 复合标志: 复合标志_) {
            常量 结果 = <复合类型_>创建类型(类型标志_.复合类型_)
            结果.复合标志 = 复合标志
            结果.基础类型 = 类型
            返回 结果
        }

        函数 创建指针类型(类型: 类型_): 指针类型_ {
            返回 <指针类型_>创建复合类型(类型, 复合标志_.指针类型_)
        }

        函数 创建数组类型(类型: 类型_, 长度: 数字 | 未定): 数组类型_ {
            常量 结果 = <数组类型_>创建复合类型(类型, 复合标志_.数组类型_)
            结果.长度 = 长度
            返回 结果
        }

        函数 创建词典类型(键类型: 类型_, 值类型: 类型_): 词典类型_ {
            常量 结果 = <词典类型_>创建类型(类型标志_.词典类型_)
            结果.键类型 = 键类型
            结果.值类型 = 值类型
            返回 结果
        }

        函数 创建文本字面量类型(长度: 数字): 文本类型_ {
            常量 结果 = 创建数组类型(字符类型, 长度)
            返回 结果
        }

        函数 创建列表类型(类型: 类型_, 长度: 数字, 容量: 数字): 列表类型_ {
            常量 结果 = <列表类型_>创建复合类型(类型, 复合标志_.列表类型_)
            结果.长度 = 长度
            结果.容量 = 容量
            返回 结果
        }

        函数 创建通信类型(类型: 类型_, 容量: 数字): 通信类型_ {
            常量 结果 = <通信类型_>创建复合类型(类型, 复合标志_.通信类型_)
            结果.容量 = 容量
            返回 结果
        }

        函数 创建只读通信类型(类型: 类型_, 容量: 数字): 只读通信类型_ {
            常量 结果 = <只读通信类型_>创建复合类型(类型, 复合标志_.只读通信类型_)
            结果.容量 = 容量
            返回 结果
        }

        函数 创建只写通信类型(类型: 类型_, 容量: 数字): 只写通信类型_ {
            常量 结果 = <只写通信类型_>创建复合类型(类型, 复合标志_.只写通信类型_)
            结果.容量 = 容量
            返回 结果
        }

        函数 创建对象类型(对象标志: 对象标志_, 符号?: 符号_): 对象类型_ {
            常量 类型 = <对象类型_>创建类型(类型标志_.对象_);
            类型.对象标志 = 对象标志;
            类型.符号 = 符号;
            返回 类型;
        }

        函数 创建真假类型(真及假: 类型_[]): 真假类型_ {
            常量 结果 = getUnionType(真及假);
            结果.标志 |= 类型标志_.真假类型_;
            (<内置类型_>结果).名称 = '真假'
            返回 <真假类型_>结果
        }

        函数 getTypeId(类型: 类型_) {
            返回 类型.id;
        }

        函数 containsType(类型组: 类型_[], 类型: 类型_): 真假 {
            返回 二分搜索(类型组, 类型, getTypeId, 比较值) >= 0;
        }

        函数 addTypesToUnion(typeSet: 类型_[], includes: 类型包括_, 类型组: 类型_[]): 类型包括_ {
            循环 (常量 类型 属于 类型组) {
                includes = addTypeToUnion(typeSet, includes, 类型);
            }
            返回 includes;
        }

        函数 containsIdenticalType(类型组: 类型_[], 类型: 类型_) {
            循环 (常量 t 属于 类型组) {
                如果 (isTypeIdenticalTo(t, 类型)) {
                    返回 为真;
                }
            }
            返回 为假;
        }

        函数 isSubtypeOfAny(source: 类型_, targets: 类型_[]): 真假 {
            循环 (常量 目标 属于 targets) {
                如果 (source !== 目标 && isTypeSubtypeOf(source, 目标)) {
                    返回 为真;
                }
            }
            返回 为假;
        }

        函数 isSetOfLiteralsFromSameEnum(类型组: 类型_[]): 真假 {
            常量 first = 类型组[0];
            如果 (first.标志 & 类型标志_.对象_ && (<对象类型_>first).对象标志 & 对象标志_.枚举成员_) {
                常量 firstEnum = first.符号!.父符号!
                循环 (变量 i = 1; i < 类型组.长度; i++) {
                    常量 other = 类型组[i];
                    如果 (!(other.标志 & 类型标志_.对象_ && ((<对象类型_>other).对象标志 & 对象标志_.枚举成员_ ||
                        !(other.标志 & 类型标志_.对象_) || !(<对象类型_>other).符号 ||
                        !(<对象类型_>other).符号!.父符号 || firstEnum !== (<对象类型_>other).符号!.父符号))) {

                        返回 为假;
                    }
                }
                返回 为真;
            }

            返回 为假;
        }

        函数 removeSubtypes(类型组: 类型_[]) {
            如果 (类型组.长度 === 0 || isSetOfLiteralsFromSameEnum(类型组)) {
                返回;
            }
            变量 i = 类型组.长度;
            判断 (i > 0) {
                i--;
                如果 (isSubtypeOfAny(类型组[i], 类型组)) {
                    按序删除项目在(类型组, i);
                }
            }
        }

        // We sort and deduplicate the constituent 类型组 based on object identity. If the subtypeReduction
        // flag is specified we also reduce the constituent 类型 set to only include 类型组 that aren't subtypes
        // of other 类型组. Subtype reduction is expensive for large union 类型组 and is possible only when union
        // 类型组 are known not to circularly reference themselves (as is the case with union 类型组 created by
        // expression constructs such as array literals and the || and ?: operators). Named 类型组 can
        // circularly reference themselves and therefore cannot be subtype reduced during their declaration.
        // For example, "类型 Item = string | (() => Item" is a named 类型 that circularly references itself.
        函数 getUnionType(类型组: 类型_[], unionReduction: UnionReduction = UnionReduction.Literal, aliasSymbol?: 符号_, aliasTypeArguments?: 类型_[]): 类型_ {
            如果 (类型组.长度 === 0) {
                返回 未定类型;
            }
            如果 (类型组.长度 === 1) {
                返回 类型组[0];
            }
            常量 typeSet: 类型_[] = [];
            常量 includes = addTypesToUnion(typeSet, 0, 类型组);
            如果 (includes & 类型包括_.通用_) {
                返回 通用类型;
            }
            假如 (unionReduction) {
                若是 UnionReduction.Subtype:
                    removeSubtypes(typeSet);
                    跳出;
            }
            如果 (typeSet.长度 === 0) {
                返回 通用类型;
            }
            返回 getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments);
        }

        // This function assumes the constituent 类型 list is sorted and deduplicated.
        函数 getUnionTypeFromSortedList(类型组: 类型_[], aliasSymbol?: 符号_, aliasTypeArguments?: 类型_[]): 类型_ {
            如果 (类型组.长度 === 0) {
                返回 通用类型;
            }
            如果 (类型组.长度 === 1) {
                返回 类型组[0];
            }
            常量 id = getTypeListId(类型组);
            变量 类型 = unionTypes.获取(id);
            如果 (!类型) {
                常量 propagatedFlags = getPropagatingFlagsOfTypes(类型组, /*excludeKinds*/ 类型标志_.未定_);
                类型 = <联合类型_>创建类型(类型标志_.联合_ | propagatedFlags);
                unionTypes.设置(id, 类型);
                类型.类型组 = 类型组;
                /*
                Note: This is the alias 符号 (or lack thereof) that we see when we first encounter this union 类型.
                For aliases of identical unions, eg `类型 T = A | B; 类型 U = A | B`, the 符号 of the first alias encountered is the aliasSymbol.
                (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.)
                It's important that we create equivalent union 类型组 only once, so that's an unfortunate side effect.
                */
                类型.aliasSymbol = aliasSymbol;
                类型.aliasTypeArguments = aliasTypeArguments;
            }
            返回 类型;
        }

        函数 getTypeFromUnionTypeNode(node: 联合类型节点_): 类型_ {
            常量 links = getNodeLinks(node);
            如果 (!links.resolvedType) {
                links.resolvedType = getUnionType(词典(node.类型组, getTypeFromTypeNode), UnionReduction.Literal,
                    获取别名符号从类型别名声明或类型声明节点(node), 获取别名类型实参从类型节点(node));
            }
            返回 links.resolvedType;
        }

        函数 获取别名类型实参从类型节点(node: 类型节点_) {
            常量 符号 = 获取别名符号从类型别名声明或类型声明节点(node);
            返回 符号 ? 获取类型的本地类型参数(符号) : 未定;
        }

        函数 获取类型的本地类型参数(符号: 符号_): 类型参数_[] {
            变量 result: 类型参数_[];
            循环 (常量 node 属于 符号.声明组!) {
                如果 (node.种类 === 语法_.结构声明_ || node.种类 === 语法_.接口声明_ || node.种类 === 语法_.类型声明_ || node.种类 === 语法_.类型别名声明_ ) {
                    常量 declaration = <结构声明_ | 接口声明_ | 类型别名声明_ | 类型声明_>node;
                    如果 (declaration.类型参数) {
                        result = appendTypeParameters(result!, declaration.类型参数);
                    }
                }
            }
            返回 result;
        }

        函数 appendTypeParameters(typeParameters: 类型参数_[], declarations: 只读数组_<类型参数声明_>): 类型参数_[] {
            循环 (变量 declaration 属于 declarations) {
                变量 tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
                typeParameters = 附加如果唯一(typeParameters, tp);
            }
            返回 typeParameters;
        }

        函数 addTypeToIntersection(typeSet: 类型_[], includes: 类型包括_, 类型: 类型_) {
            常量 标志 = 类型.标志;
            如果 (标志 & 类型标志_.交叉_) {
                includes = addTypesToIntersection(typeSet, includes, (<交叉类型_>类型).类型组);
            }
            否则 如果 (标志 & 类型标志_.通用_) {
                includes |= 类型包括_.通用_;
            }
            否则 如果 (getObjectFlags(类型) & 对象标志_.匿名_ && isEmptyObjectType(类型)) {
                includes |= 类型包括_.EmptyObject;
            }
            否则 如果 (!包含(typeSet, 类型)) {
                如果 (标志 & 类型标志_.对象_) {
                    includes |= 类型包括_.对象类型_;
                }
                如果 (标志 & 类型标志_.联合_) {
                    includes |= 类型包括_.联合_;
                }
                如果 (!(标志 & 类型标志_.对象_ && (<对象类型_>类型).对象标志 & 对象标志_.匿名_ &&
                    类型.符号 && 类型.符号.标志 & (符号标志_.函数_ | 符号标志_.方法_) && containsIdenticalType(typeSet, 类型))) {
                    typeSet.压入(类型);
                }
            }
            返回 includes;
        }

        // Add the given 类型组 to the given 类型 set. Order is preserved, freshness is removed from literal
        // 类型组, duplicates are removed, and nested 类型组 of the given 种类 are flattened into the set.
        函数 addTypesToIntersection(typeSet: 类型_[], includes: 类型包括_, 类型组: 类型_[]) {
            循环 (常量 类型 属于 类型组) {
                includes = addTypeToIntersection(typeSet, includes, getRegularTypeOfLiteralType(类型));
            }
            返回 includes;
        }

        函数 getRegularTypeOfLiteralType(类型: 类型_): 类型_ {
            返回 类型.标志 & 类型标志_.联合_ ? getUnionType(sameMap((<联合类型_>类型).类型组, getRegularTypeOfLiteralType)) :
                类型;
        }

        // We normalize combinations of intersection and union 类型组 based on the distributive property of the '&'
        // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection
        // 类型组 with union 类型 constituents into equivalent union 类型组 with intersection 类型 constituents and
        // effectively ensure that union 类型组 are always at the top level in 类型 representations.
        //
        // We do not perform structural deduplication on intersection 类型组. 交叉_ 类型组 are created only by the &
        // 类型 operator and we can't reduce those because we want to support recursive intersection 类型组. For example,
        // a 类型 alias of the form "类型 List<T> = T & { next: List<T> }" cannot be reduced during its declaration.
        // Also, unlike union 类型组, the order of the constituent 类型组 is preserved in order that overload resolution
        // for intersections of 类型组 with signatures can be deterministic.
        函数 getIntersectionType(类型组: 类型_[], aliasSymbol?: 符号_, aliasTypeArguments?: 类型_[]): 类型_ {
            如果 (类型组.长度 === 0) {
                返回 通用类型;
            }
            常量 typeSet: 类型_[] = [];
            常量 includes = addTypesToIntersection(typeSet, 0, 类型组);
            如果 (includes & 类型包括_.通用_) {
                返回 通用类型
            }
            如果 (includes & 类型包括_.EmptyObject && !(includes & 类型包括_.对象类型_)) {
                typeSet.压入(通用类型);
            }
            如果 (typeSet.长度 === 1) {
                返回 typeSet[0];
            }
            如果 (includes & 类型包括_.联合_) {
                // We are attempting to construct a 类型 of the form X & (A | B) & Y. Transform this into a 类型 of
                // the form X & A & Y | X & B & Y and recursively reduce until no union 类型 constituents remain.
                常量 unionIndex = findIndex(typeSet, t => (t.标志 & 类型标志_.联合_) !== 0);
                常量 unionType = <联合类型_>typeSet[unionIndex];
                返回 getUnionType(词典(unionType.类型组, t => getIntersectionType(replaceElement(typeSet, unionIndex, t))),
                    UnionReduction.Literal, aliasSymbol, aliasTypeArguments);
            }
            常量 id = getTypeListId(typeSet);
            变量 类型 = intersectionTypes.获取(id);
            如果 (!类型) {
                常量 propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 类型标志_.通用_);
                类型 = <交叉类型_>创建类型(类型标志_.交叉_ || propagatedFlags);
                intersectionTypes.设置(id, 类型);
                类型.类型组 = typeSet;
                类型.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`.
                类型.aliasTypeArguments = aliasTypeArguments;
            }
            返回 类型;
        }

        函数 getTypeFromIntersectionTypeNode(node: 交叉类型节点_): 类型_ {
            常量 links = getNodeLinks(node);
            如果 (!links.resolvedType) {
                links.resolvedType = getIntersectionType(词典(node.类型组, getTypeFromTypeNode),
                    获取别名符号从类型别名声明或类型声明节点(node), 获取别名类型实参从类型节点(node));
            }
            返回 links.resolvedType;
        }


        函数 addTypeToUnion(typeSet: 类型_[], includes: 类型包括_, 类型: 类型_) {
            常量 标志 = 类型.标志;
            如果 (标志 & 类型标志_.联合_) {
                includes = addTypesToUnion(typeSet, includes, (<联合类型_>类型).类型组);
            }
            否则 如果 (标志 & 类型标志_.通用_) {
                includes |= 类型包括_.通用_;
            }
            否则 {
                如果 (标志 & 类型标志_.数字类型_) includes |= 类型包括_.Number;

                常量 len = typeSet.长度;
                常量 index = len && 类型.id > typeSet[len - 1].id ? ~len : 二分搜索(typeSet, 类型, getTypeId, 比较值);
                如果 (index < 0) {
                    如果 (!(标志 & 类型标志_.对象_ && (<对象类型_>类型).对象标志 & 对象标志_.匿名_ &&
                        类型.符号 && 类型.符号.标志 & (符号标志_.函数_ | 符号标志_.方法_) && containsIdenticalType(typeSet, 类型))) {
                        typeSet.分离(~index, 0, 类型);
                    }
                }
            }

            返回 includes;
        }


        函数 getTypeListId(类型组: 只读数组_<类型_> | 未定) {
            变量 结果 = "";
            如果 (类型组) {
                常量 长 = 类型组.长度;
                变量 i = 0;
                判断 (i < 长) {
                    常量 开始Id = 类型组[i].id;
                    变量 数量 = 1;
                    判断 (i + 数量 < 长 && 类型组[i + 数量].id === 开始Id + 数量) {
                        数量++;
                    }
                    如果 (结果.长度) {
                        结果 += ",";
                    }
                    结果 += 开始Id;
                    如果 (数量 > 1) {
                        结果 += ":" + 数量;
                    }
                    i += 数量;
                }
            }
            返回 结果;
        }

        函数 getPropagatingFlagsOfTypes(类型组: 类型_[], 排除种类: 类型标志_): 类型标志_ {
            变量 结果: 类型标志_ = 0;
            循环 (常量 类型 属于 类型组) {
                如果 (!(类型.标志 & 排除种类)) {
                    结果 |= 类型.标志;
                }
            }
            返回 结果 & 类型标志_.PropagatingFlags
        }

        // TYPE CHECKING
        函数 isTypeIdenticalTo(source: 类型_, 目标: 类型_): 真假 {
            返回 isTypeRelatedTo(source, 目标, 身份关系);
        }

        函数 compareTypesIdentical(source: 类型_, 目标: 类型_): Ternary {
            返回 isTypeRelatedTo(source, 目标, 身份关系) ? Ternary.真_ : Ternary.假_;
        }

        函数 compareTypesAssignable(source: 类型_, 目标: 类型_): Ternary {
            返回 isTypeRelatedTo(source, 目标, 可赋值关系) ? Ternary.真_ : Ternary.假_;
        }

        函数 isTypeSubtypeOf(source: 类型_, 目标: 类型_): 真假 {
            返回 isTypeRelatedTo(source, 目标, 子类型关系);
        }

        函数 isTypeAssignableTo(source: 类型_, 目标: 类型_): 真假 {
            返回 isTypeRelatedTo(source, 目标, 可赋值关系);
        }

        函数 isTypeComparableTo(source: 类型_, 目标: 类型_): 真假 {
            返回 isTypeRelatedTo(source, 目标, 可比较关系);
        }

        /*
        函数 areTypesComparable(type1: 类型_, type2: 类型_): 真假 {
            返回 isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1);
        }
        */

        函数 checkTypeAssignableTo(source: 类型_, 目标: 类型_, errorNode: 节点_, headMessage?: 诊断信息_, containingMessageChain?: () => 诊断信息链_ | 未定): 真假 {
            返回 checkTypeRelatedTo(source, 目标, 可赋值关系, errorNode, headMessage, containingMessageChain);
        }
        /*

        函数 checkTypeComparableTo(source: 类型_, 目标: 类型_, errorNode: 节点_, headMessage?: 诊断信息_, containingMessageChain?: () => 诊断信息链_ | 未定): 真假 {
            返回 checkTypeRelatedTo(source, 目标, 可比较关系, errorNode, headMessage, containingMessageChain);
        }

        函数 isSignatureAssignableTo(source: 签名_,
            目标: 签名_,
            ignoreReturnTypes: 真假): 真假 {
            返回 compareSignaturesRelated(source, 目标, CallbackCheck.None, ignoreReturnTypes, 为假,
                未定!, compareTypesAssignable) !== Ternary.假_;
        }
        */

        类型 ErrorReporter = (message: 诊断信息_, arg0?: 文字, arg1?: 文字) => 无值;

        函数 compareSignaturesIdentical(source: 签名_, 目标: 签名_, partialMatch: 真假, ignoreThisTypes: 真假, ignoreReturnTypes: 真假, compareTypes: (s: 类型_, t: 类型_) => Ternary): Ternary {
            // TODO (drosen): De-duplicate code between related functions.
            ignoreThisTypes
            如果 (source === 目标) {
                返回 Ternary.真_;
            }
            如果 (!(isMatchingSignature(source, 目标, partialMatch))) {
                返回 Ternary.假_;
            }

            变量 result = Ternary.真_;

            常量 targetLen = 目标.参数.长度;

            循环 (变量 i = 0; i < targetLen; i++) {
                常量 s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.参数[i]);
                常量 t = isRestParameterIndex(目标, i) ? getRestTypeOfSignature(目标) : getTypeOfParameter(目标.参数[i]);
                常量 related = compareTypes(s, t);
                如果 (!related) {
                    返回 Ternary.假_;
                }
                result &= related;
            }
            如果 (!ignoreReturnTypes) {
                result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(目标));
            }
            返回 result;
        }

        /**
         * See signatureRelatedTo, compareSignaturesIdentical
         */
        函数 compareSignaturesRelated(source: 签名_,
            目标: 签名_,
            callbackCheck: CallbackCheck,
            ignoreReturnTypes: 真假,
            reportErrors: 真假,
            errorReporter: ErrorReporter,
            compareTypes: 类型比较器_): Ternary {
            // TODO (drosen): De-duplicate code between related functions.
            如果 (source === 目标) {
                返回 Ternary.真_;
            }
            如果 (!目标.具有剩余参数 && source.minArgumentCount > 目标.参数.长度) {
                返回 Ternary.假_;
            }

            常量 种类 = 目标.declaration ? 目标.declaration.种类 : 语法_.未知_;

            常量 strictVariance = !callbackCheck && 种类 !== 语法_.方法声明_ && 种类 !== 语法_.方法签名_;

            变量 result = Ternary.真_;

            常量 sourceMax = source.具有剩余参数 ? source.参数.长度 - 1 : source.参数.长度

            常量 targetMax = 目标.具有剩余参数 ? 目标.参数.长度 - 1 : 目标.参数.长度

            常量 checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, 目标, targetMax);

            常量 sourceParams = source.参数;
            常量 targetParams = 目标.参数;

            循环 (变量 i = 0; i < checkCount; i++) {
                常量 sourceType = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source);

                常量 targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(目标);

                常量 sourceSig = callbackCheck ? 未定! : getSingleCallSignature(sourceType)!;

                常量 targetSig = callbackCheck ? 未定! : getSingleCallSignature(sourceType)!;

                常量 callbacks = sourceSig && targetSig;

                常量 related = callbacks ?
                    compareSignaturesRelated(targetSig, sourceSig, strictVariance ? CallbackCheck.Strict : CallbackCheck.Bivariant, /*ignoreReturnTypes*/ 为假, reportErrors, errorReporter, compareTypes) :
                    !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ 为假) || compareTypes(targetType, sourceType, reportErrors);
                如果 (!related) {
                    如果 (reportErrors) {
                        errorReporter(诊断信息_.Types_of_parameters_0_and_1_are_incompatible,
                            symbolName(sourceParams[i < sourceMax ? i : sourceMax]),
                            symbolName(targetParams[i < targetMax ? i : targetMax]));
                    }
                    返回 Ternary.假_;
                }
                result &= related;
            }

            如果 (!ignoreReturnTypes) {
                常量 targetReturnType = getReturnTypeOfSignature(目标);
                如果 (!targetReturnType) {
                    返回 result;
                }
                常量 sourceReturnType = getReturnTypeOfSignature(source);
                result &= callbackCheck === CallbackCheck.Bivariant && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ 为假) ||
                    compareTypes(sourceReturnType, targetReturnType, reportErrors);
            }
            返回 result;
        }

        函数 isTypeRelatedTo(source: 类型_, 目标: 类型_, relation: 词典_<关系比较结果_>) {
            如果 (source === 目标 || relation === 可比较关系 && isSimpleTypeRelatedTo(目标, source, relation) || relation !== 身份关系 && isSimpleTypeRelatedTo(source, 目标, relation)) {
                返回 为真;
            }
            如果 (source.标志 & 类型标志_.对象_ && 目标.标志 & 类型标志_.对象_) {
                常量 related = relation.获取(getRelationKey(source, 目标, relation));
                如果 (related !== 未定) {
                    返回 related === 关系比较结果_.成功的_;
                }
            }
            如果 (source.标志 & 类型标志_.结构化类型_ || 目标.标志 & 类型标志_.结构化类型_) {
                返回 checkTypeRelatedTo(source, 目标, relation, 未定!);
            }
            返回 为假;
        }
        /*        
        函数 isPropertyIdenticalTo(sourceProp: 符号_, targetProp: 符号_): 真假 {
            返回 compareProperties(sourceProp, targetProp, compareTypesIdentical) !== Ternary.假_;
        }
        */

        函数 compareProperties(sourceProp: 符号_, targetProp: 符号_, compareTypes: (source: 类型_, 目标: 类型_) => Ternary): Ternary {
            如果 (sourceProp === targetProp) {
                返回 Ternary.真_
            }
            返回 compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
        }

        函数 isRestParameterIndex(signature: 签名_, parameterIndex: 数字) {
            返回 signature.具有剩余参数 && parameterIndex >= signature.参数.长度 - 1;
        }

        函数 isMatchingSignature(source: 签名_, 目标: 签名_, partialMatch: 真假) {
            // A source signature matches a 目标 signature 如果 the two signatures have the same number of required,
            // optional, and rest parameters.
            如果 (source.参数.长度 === 目标.参数.长度 &&
                source.minArgumentCount === 目标.minArgumentCount &&
                source.具有剩余参数 === 目标.具有剩余参数) {
                返回 为真;
            }
            // A source signature partially matches a 目标 signature 如果 the 目标 signature has no fewer required
            // parameters and no more overall parameters than the source signature (where a signature with a rest
            // parameter is always considered to have more overall parameters than one without).
            常量 sourceRestCount = source.具有剩余参数 ? 1 : 0;
            常量 targetRestCount = 目标.具有剩余参数 ? 1 : 0;
            如果 (partialMatch && source.minArgumentCount <= 目标.minArgumentCount && (
                sourceRestCount > targetRestCount ||
                sourceRestCount === targetRestCount && source.参数.长度 >= 目标.参数.长度)) {
                返回 为真;
            }
            返回 为假;
        }

        函数 checkTypeRelatedTo(
            source: 类型_,
            目标: 类型_,
            relation: 词典_<关系比较结果_>,
            errorNode: 节点_,
            headMessage?: 诊断信息_,
            containingMessageChain?: () => 诊断信息链_ | 未定): 真假 {

            变量 errorInfo: 诊断信息链_;
            变量 maybeKeys: 文字[];
            变量 sourceStack: 类型_[];
            变量 targetStack: 类型_[];
            变量 maybeCount = 0;
            变量 depth = 0;
            变量 expandingFlags = ExpandingFlags.None;
            变量 overflow = 为假;

            调试_.断言(relation !== 身份关系 || !errorNode, 'no error reporting in identity checking');

            常量 result = isRelatedTo(source, 目标, !!errorNode, headMessage);
            如果 (overflow) {
                error(errorNode, 诊断信息_.Excessive_stack_depth_comparing_types_0_and_1, 'typeToString(source)', 'typeToString(目标)');
            }
            否则 如果 (errorInfo!) {
                如果 (containingMessageChain) {
                    常量 chain = containingMessageChain();
                    如果 (chain) {
                        errorInfo = 连接诊断信息消息链组(chain, errorInfo!);
                    }
                }

                diagnostics.添加(创建诊断从节点从消息链(errorNode, errorInfo!));
            }
            返回 result !== Ternary.假_;

            函数 reportError(message: 诊断信息_, arg0?: 文字, arg1?: 文字, arg2?: 文字): 无值 {
                调试_.断言(!!errorNode);
                errorInfo = 诊断消息链(errorInfo, message, arg0!, arg1!, arg2!);
            }

            函数 reportRelationError(message: 诊断信息_, source: 类型_, 目标: 类型_) {
                source
                目标
                变量 sourceType = 'typeToString(source)';
                变量 targetType = 'typeToString(目标)';
                如果 (sourceType === targetType) {
                    sourceType = 'typeToString(source, 未定, TypeFormatFlags.UseFullyQualifiedType)';
                    targetType = 'typeToString(目标, 未定, TypeFormatFlags.UseFullyQualifiedType)';
                }

                如果 (!message) {
                    如果 (relation === 可比较关系) {
                        message = 诊断信息_.Type_0_is_not_comparable_to_type_1;
                    }
                    否则 如果 (sourceType === targetType) {
                        message = 诊断信息_.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated;
                    }
                    否则 {
                        message = 诊断信息_.Type_0_is_not_assignable_to_type_1;
                    }
                }

                reportError(message, sourceType, targetType);
            }

            函数 isRelatedTo(source: 类型_, 目标: 类型_, reportErrors?: 真假, headMessage?: 诊断信息_): Ternary {
                // both 类型组 are the same - covers 'they are the same primitive 类型 or both are Any' or the same 类型 parameter cases
                如果 (source === 目标) 返回 Ternary.真_;

                如果 (relation === 身份关系) {
                    返回 isIdenticalTo(source, 目标);
                }

                如果 (relation === 可比较关系 && isSimpleTypeRelatedTo(目标, source, relation) || isSimpleTypeRelatedTo(source, 目标, relation)) 返回 Ternary.真_;


                如果 (relation !== 可比较关系 && !(目标.标志 & 类型标志_.联合_) &&
                    (getPropertiesOfType(source).长度 > 0 || getSignaturesOfType(source).长度 !== 0) &&
                    isWeakType(目标) &&
                    !hasCommonProperties(source, 目标)) {
                    如果 (reportErrors) {
                        常量 calls = getSignaturesOfType(source);

                        如果 (calls.长度 > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), 目标, 为假)) {
                            reportError(诊断信息_.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, 'typeToString(source)', 'typeToString(目标)');
                        }
                        否则 {
                            reportError(诊断信息_.Type_0_has_no_properties_in_common_with_type_1, 'typeToString(source)', 'typeToString(目标)');
                        }
                    }
                    返回 Ternary.假_;
                }

                变量 result = Ternary.假_;
                常量 saveErrorInfo = errorInfo;

                // Note that these checks are specifically ordered to produce correct results. In particular,
                // we need to deconstruct unions before intersections (because unions are always at the top),
                // and we need to handle "each" relations before "some" relations 循环 the same 种类 属于 类型.
                如果 (source.标志 & 类型标志_.联合_) {
                    result = relation === 可比较关系 ?
                        someTypeRelatedToType(source 转为 联合类型_, 目标, 为假) :
                        eachTypeRelatedToType(source 转为 联合类型_, 目标, 为假);
                }
                否则 {
                    如果 (目标.标志 & 类型标志_.联合_) {
                        result = typeRelatedToSomeType(source, <联合类型_>目标, 为假!);
                    }
                    如果 (!result && (source.标志 & 类型标志_.结构化类型_ || 目标.标志 & 类型标志_.结构化类型_)) {
                        如果 (result = recursiveTypeRelatedTo(source, 目标, reportErrors!)) {
                            errorInfo = saveErrorInfo;
                        }
                    }
                }

                如果 (!result && reportErrors) {
                    reportRelationError(headMessage!, source, 目标);
                }
                返回 result;
            }

            函数 isIdenticalTo(source: 类型_, 目标: 类型_): Ternary {
                变量 result: Ternary;
                常量 标志 = source.标志 & 目标.标志;
                如果 (标志 & 类型标志_.对象_) {
                    返回 recursiveTypeRelatedTo(source, 目标, 为假);
                }
                如果 (标志 & 类型标志_.联合_) {
                    如果 (result = eachTypeRelatedToSomeType(<联合类型_>source, <联合类型_>目标)) {
                        如果 (result &= eachTypeRelatedToSomeType(<联合类型_>目标, <联合类型_>source)) {
                            返回 result;
                        }
                    }
                }
                返回 Ternary.假_;
            }

            函数 eachTypeRelatedToSomeType(source: 联合类型_, 目标: 联合类型_): Ternary {
                变量 result = Ternary.真_;
                常量 sourceTypes = source.类型组;
                循环 (常量 sourceType 属于 sourceTypes) {
                    常量 related = typeRelatedToSomeType(sourceType, 目标, 为假);
                    如果 (!related) {
                        返回 Ternary.假_;
                    }
                    result &= related;
                }
                返回 result;
            }

            函数 typeRelatedToSomeType(source: 类型_, 目标: 联合类型_, reportErrors: 真假): Ternary {
                常量 targetTypes = 目标.类型组;
                如果 (目标.标志 & 类型标志_.联合_ && containsType(targetTypes, source)) {
                    返回 Ternary.真_;
                }
                循环 (常量 类型 属于 targetTypes) {
                    常量 related = isRelatedTo(source, 类型, 为假);
                    如果 (related) {
                        返回 related;
                    }
                }
                如果 (reportErrors) {
                    常量 discriminantType = findMatchingDiscriminantType(source, 目标);
                    isRelatedTo(source, discriminantType || targetTypes[targetTypes.长度 - 1], 为真);
                }
                返回 Ternary.假_;
            }

            函数 findDiscriminantProperties(sourceProperties: 符号_[], 目标: 类型_): 符号_[] | 未定 {
                变量 result: 符号_[];
                循环 (常量 sourceProperty 属于 sourceProperties) {
                    如果 (isDiscriminantProperty(目标, sourceProperty.名称)) {
                        如果 (result!) {
                            result!.压入(sourceProperty);
                            继续;
                        }
                        result = [sourceProperty];
                    }
                }
                返回 result!;
            }

            函数 isDiscriminantProperty(目标: 类型_, 名称: 文字) {
                名称
                目标
                返回 为假
            }

            // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly
            函数 findMatchingDiscriminantType(source: 类型_, 目标: 联合类型_) {
                变量 match: 类型_;
                常量 sourceProperties = getPropertiesOfObjectType(source);
                如果 (sourceProperties) {
                    常量 sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, 目标);
                    如果 (sourcePropertiesFiltered) {
                        循环 (常量 sourceProperty 属于 sourcePropertiesFiltered) {
                            常量 sourceType = getTypeOfSymbol(sourceProperty);
                            循环 (常量 类型 属于 目标.类型组) {

                                常量 targetType = getTypeOfPropertyOfType(类型, sourceProperty.名称);

                                如果 (targetType && isRelatedTo(sourceType, targetType)) {
                                    如果 (类型 === match!) 继续; // Finding multiple fields which discriminate to the same 类型 is fine
                                    如果 (match!) {
                                        返回 未定;
                                    }
                                    match = 类型;
                                }
                            }
                        }
                    }
                }
                返回 match!;
            }

            函数 someTypeRelatedToType(source: 联合类型_, 目标: 类型_, reportErrors: 真假): Ternary {
                常量 sourceTypes = source.类型组;
                如果 (source.标志 & 类型标志_.联合_ && containsType(sourceTypes, 目标)) {
                    返回 Ternary.真_;
                }
                常量 len = sourceTypes.长度;
                循环 (变量 i = 0; i < len; i++) {
                    常量 related = isRelatedTo(sourceTypes[i], 目标, reportErrors && i === len - 1);
                    如果 (related) {
                        返回 related;
                    }
                }
                返回 Ternary.假_;
            }

            函数 eachTypeRelatedToType(source: 联合类型_, 目标: 类型_, reportErrors: 真假): Ternary {
                变量 result = Ternary.真_;
                常量 sourceTypes = source.类型组;
                循环 (常量 sourceType 属于 sourceTypes) {
                    常量 related = isRelatedTo(sourceType, 目标, reportErrors);
                    如果 (!related) {
                        返回 Ternary.假_;
                    }
                    result &= related;
                }
                返回 result;
            }

            函数 isDeeplyNestedType(类型: 类型_, stack: 类型_[], depth: 数字): 真假 {
                // We track all object 类型组 that have an associated 符号 (representing the origin of the 类型)
                如果 (depth >= 5 && 类型.标志 & 类型标志_.对象_) {
                    常量 符号 = 类型.符号;
                    如果 (符号) {
                        变量 count = 0;
                        循环 (变量 i = 0; i < depth; i++) {
                            常量 t = stack[i];
                            如果 (t.标志 & 类型标志_.对象_ && t.符号 === 符号) {
                                count++;
                                如果 (count >= 5) 返回 为真;
                            }
                        }
                    }
                }
                返回 为假;
            }

            // Determine 如果 possibly recursive 类型组 are related. First, check 如果 the result is already available in the global cache.
            // Second, check 如果 we have already started a comparison 属于 the given two 类型组 in which 若是 we assume the result to be true.
            // Third, check 如果 both 类型组 are part 属于 deeply nested chains 属于 generic 类型 instantiations and 如果 so assume the 类型组 are
            // equal and infinitely expanding. Fourth, 如果 we have reached a depth 属于 100 nested comparisons, assume we have runaway recursion
            // and issue an error. Otherwise, actually compare the structure 属于 the two 类型组.
            函数 recursiveTypeRelatedTo(source: 类型_, 目标: 类型_, reportErrors: 真假): Ternary {
                如果 (overflow) {
                    返回 Ternary.假_;
                }
                常量 id = getRelationKey(source, 目标, relation);
                常量 related = relation.获取(id);
                如果 (related !== 未定) {
                    如果 (reportErrors && related === 关系比较结果_.失败的_) {
                        // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
                        // failure and continue computing the relation such that errors get reported.
                        relation.设置(id, 关系比较结果_.失败并报告_);
                    }
                    否则 {
                        返回 related === 关系比较结果_.成功的_ ? Ternary.真_ : Ternary.假_;
                    }
                }
                如果 (!maybeKeys) {
                    maybeKeys = [];
                    sourceStack = [];
                    targetStack = [];
                }
                否则 {
                    循环 (变量 i = 0; i < maybeCount; i++) {
                        // If source and 目标 are already being compared, consider them related with assumptions
                        如果 (id === maybeKeys[i]) {
                            返回 Ternary.也许_;
                        }
                    }
                    如果 (depth === 100) {
                        overflow = 为真;
                        返回 Ternary.假_;
                    }
                }
                常量 maybeStart = maybeCount;
                maybeKeys[maybeCount] = id;
                maybeCount++;
                sourceStack[depth] = source;
                targetStack[depth] = 目标;
                depth++;
                常量 saveExpandingFlags = expandingFlags;
                如果 (!(expandingFlags & ExpandingFlags.Source) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= ExpandingFlags.Source;
                如果 (!(expandingFlags & ExpandingFlags.Target) && isDeeplyNestedType(目标, targetStack, depth)) expandingFlags |= ExpandingFlags.Target;
                常量 result = expandingFlags !== ExpandingFlags.Both ? structuredTypeRelatedTo(source, 目标, reportErrors) : Ternary.也许_;
                expandingFlags = saveExpandingFlags;
                depth--;
                如果 (result) {
                    如果 (result === Ternary.真_ || depth === 0) {
                        // If result is definitely true, record all maybe keys as having succeeded
                        循环 (变量 i = maybeStart; i < maybeCount; i++) {
                            relation.设置(maybeKeys[i], 关系比较结果_.成功的_);
                        }
                        maybeCount = maybeStart;
                    }
                }
                否则 {
                    // A false result goes straight into global cache (when something is false under
                    // assumptions it will also be false without assumptions)
                    relation.设置(id, reportErrors ? 关系比较结果_.失败并报告_ : 关系比较结果_.失败的_);
                    maybeCount = maybeStart;
                }
                返回 result;
            }

            函数 structuredTypeRelatedTo(source: 类型_, 目标: 类型_, reportErrors: 真假): Ternary {
                变量 result: Ternary;
                变量 originalErrorInfo!: 诊断信息链_;
                常量 saveErrorInfo = errorInfo;
                如果 (source.标志 & 类型标志_.类型参数_) {
                    变量 constraint = getConstraintForRelation(<类型参数_>source);
                    // A 类型 parameter with no constraint is not related to the non-primitive object 类型.
                    如果 (constraint) {
                        常量 reportConstraintErrors = reportErrors && constraint !== 通用类型;
                        如果 (result = isRelatedTo(constraint, 目标, reportConstraintErrors)) {
                            errorInfo = saveErrorInfo;
                            返回 result;
                        }
                    }
                }
                否则 {
                    如果 (getObjectFlags(source) & 对象标志_.引用_ && getObjectFlags(目标) & 对象标志_.引用_ && (<类型引用_>source).目标 === (<类型引用_>目标).目标 && !(getObjectFlags(source) & 对象标志_.标记类型_ || getObjectFlags(目标) & 对象标志_.标记类型_)) {
                        // We have 类型 references to the same generic 类型, and the 类型 references are not marker
                        // 类型 references (which are intended by be compared structurally). Obtain the variance
                        // information for the 类型 parameters and relate the 类型 arguments accordingly.
                        常量 variances = getVariances((<类型引用_>source).目标);
                        如果 (result = typeArgumentsRelatedTo(<类型引用_>source, <类型引用_>目标, variances, reportErrors)) {
                            返回 result;
                        }
                        // The 类型 arguments did not relate appropriately, but it may be because we have no variance
                        // information (in which case typeArgumentsRelatedTo defaulted to covariance for all 类型
                        // arguments). It might also be the case that the 目标 类型 has a 'void' 类型 argument for
                        // a covariant 类型 parameter that is only used in 返回 positions within the generic 类型
                        // (in which case any 类型 argument is permitted on the source side). In those cases we proceed
                        // with a structural comparison. Otherwise, we know for certain the instantiations aren't
                        // related and we can 返回 here.
                        如果 (variances !== 空数组 && !hasCovariantVoidArgument(<类型引用_>目标, variances)) {
                            // In some cases generic types that are covariant in regular 类型 checking mode become
                            // invariant in --strictFunctionTypes mode because one or more 类型 parameters are used in
                            // both co- and contravariant positions. In order to make it easier to diagnose *why* such
                            // types are invariant, 如果 any of the 类型 parameters are invariant we reset the reported
                            // errors and instead force a structural comparison (which will include elaborations that
                            // reveal the reason).
                            如果 (!(reportErrors && 某些(variances, v => v === Variance.Invariant))) {
                                返回 Ternary.假_;
                            }
                            // We remember the original error information so we can restore it in case the structural
                            // comparison unexpectedly succeeds. This can happen when the structural comparison result
                            // is a Ternary.Maybe for example caused by the recursion depth limiter.
                            originalErrorInfo = errorInfo;
                            errorInfo = saveErrorInfo;
                        }
                    }
                    // Even 如果 relationship doesn't hold for unions, intersections, or generic 类型 references,
                    // it may hold in a structural comparison.
                    如果 (relation !== 身份关系) {
                        source = getApparentType(source);
                    }
                    // In a check of the form X = A & B, we will have previously checked 如果 A relates to X or B relates
                    // to X. Failing both of those we want to check 如果 the aggregation of A and B's members structurally
                    // relates to X. Thus, we include intersection types on the source side here.
                    如果 (source.标志 & (类型标志_.对象_ | 类型标志_.交叉_) && 目标.标志 & 类型标志_.对象_) {
                        // Report structural errors only 如果 we haven't reported any errors yet
                        常量 reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo;
                        // An empty object 类型 is related to any mapped 类型 that includes a '?' modifier.

                        result = propertiesRelatedTo(source, 目标, reportStructuralErrors);
                        如果 (result) {
                            result &= signaturesRelatedTo(source, 目标, reportStructuralErrors);
                            如果 (result) {
                                result &= signaturesRelatedTo(source, 目标, reportStructuralErrors)
                            }
                        }

                        如果 (result) {
                            如果 (!originalErrorInfo) {
                                errorInfo = saveErrorInfo;
                                返回 result;
                            }
                            errorInfo = originalErrorInfo;
                        }
                    }
                }
                返回 Ternary.假_;
            }

            函数 typeArgumentsRelatedTo(source: 类型引用_, 目标: 类型引用_, variances: Variance[], reportErrors: 真假): Ternary {
                常量 sources = source.类型实参 || 空数组;
                常量 targets = 目标.类型实参 || 空数组;
                如果 (sources.长度 !== targets.长度 && relation === 身份关系) {
                    返回 Ternary.假_;
                }
                常量 length = sources.长度 <= targets.长度 ? sources.长度 : targets.长度;
                变量 result = Ternary.真_;
                循环 (变量 i = 0; i < length; i++) {
                    // When variance information isn't available we default to covariance. This happens
                    // in the process of computing variance information for recursive types and when
                    // comparing 'this' 类型 arguments.
                    常量 variance = i < variances.长度 ? variances[i] : Variance.Covariant;
                    // We ignore arguments for independent 类型 parameters (because they're never witnessed).
                    如果 (variance !== Variance.Independent) {
                        常量 s = sources[i];
                        常量 t = targets[i];
                        变量 related = Ternary.真_;
                        如果 (variance === Variance.Covariant) {
                            related = isRelatedTo(s, t, reportErrors);
                        }
                        否则 如果 (variance === Variance.Contravariant) {
                            related = isRelatedTo(t, s, reportErrors);
                        }
                        否则 如果 (variance === Variance.Bivariant) {
                            // In the bivariant case we first compare contravariantly without reporting
                            // errors. Then, 如果 that doesn't succeed, we compare covariantly with error
                            // reporting. Thus, error elaboration will be based on the the covariant check,
                            // which is generally easier to reason about.
                            related = isRelatedTo(t, s, /*reportErrors*/ 为假);
                            如果 (!related) {
                                related = isRelatedTo(s, t, reportErrors);
                            }
                        }
                        否则 {
                            // In the invariant case we first compare covariantly, and only when that
                            // succeeds do we proceed to compare contravariantly. Thus, error elaboration
                            // will typically be based on the covariant check.
                            related = isRelatedTo(s, t, reportErrors);
                            如果 (related) {
                                related &= isRelatedTo(t, s, reportErrors);
                            }
                        }
                        如果 (!related) {
                            返回 Ternary.假_;
                        }
                        result &= related;
                    }
                }
                返回 result;
            }

            函数 getConstraintForRelation(类型: 类型_) {
                返回 relation === 绝对可以赋值关系 ? 未定 : getConstraintOfType(类型);
            }

            函数 getConstraintOfType(类型: 可实例化类型_ | 联合或交叉类型_): 类型_ | 未定 {
                返回 类型.标志 & 类型标志_.类型参数_ ? getConstraintOfTypeParameter(<类型参数_>类型) : getBaseConstraintOfType(类型);
            }

            // Return true 如果 the given 类型 reference has a 'void' 类型 argument for a covariant 类型 parameter.
            // See comment at call in recursiveTypeRelatedTo for when this case matters.
            函数 hasCovariantVoidArgument(类型: 类型引用_, variances: Variance[]): 真假 {
                循环 (变量 i = 0; i < variances.长度; i++) {
                    如果 (variances[i] === Variance.Covariant && 类型.类型实参![i].标志 & 类型标志_.无值_) {
                        返回 为真;
                    }
                }
                返回 为假;
            }

            函数 propertiesRelatedTo(source: 类型_, 目标: 类型_, reportErrors: 真假): Ternary {
                如果 (relation === 身份关系) {
                    返回 propertiesIdenticalTo(source, 目标);
                }

                常量 unmatchedProperty = getUnmatchedProperty(source, 目标);
                如果 (unmatchedProperty) {
                    如果 (reportErrors) {
                        reportError(诊断信息_.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), `typeToString(source)`);
                    }
                    返回 Ternary.假_;
                }

                变量 result = Ternary.真_;
                常量 properties = getPropertiesOfObjectType(目标);

                循环 (常量 targetProp 属于 properties) {
                    常量 sourceProp = getPropertyOfType(source, targetProp.名称);
                    如果 (sourceProp && sourceProp !== targetProp) {
                        常量 sourcePropFlags = getDeclarationModifierFlagsFromSymbol(sourceProp);
                        常量 targetPropFlags = getDeclarationModifierFlagsFromSymbol(targetProp);

                        如果 (sourcePropFlags & 修饰符组_.Private || targetPropFlags & 修饰符组_.Private) {
                            如果 (getCheckFlags(sourceProp) & CheckFlags.ContainsPrivate) {
                                如果 (reportErrors) {
                                    reportError(诊断信息_.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), `typeToString(source)`);
                                }
                                返回 Ternary.假_;
                            }
                            如果 (sourceProp.值声明 !== targetProp.值声明) {
                                如果 (reportErrors) {
                                    如果 (sourcePropFlags & 修饰符组_.Private && targetPropFlags & 修饰符组_.Private) {
                                        reportError(诊断信息_.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp));
                                    }
                                    否则 {
                                        reportError(诊断信息_.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp),
                                            'typeToString(sourcePropFlags & 修饰符组_.Private ? source : 目标)',
                                            'typeToString(sourcePropFlags & 修饰符组_.Private ? 目标 : source)');
                                    }
                                }
                                返回 Ternary.假_;
                            }
                        }
                        常量 related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors);
                        如果 (!related) {
                            如果 (reportErrors) {
                                reportError(诊断信息_.Types_of_property_0_are_incompatible, symbolToString(targetProp));
                            }
                            返回 Ternary.假_;
                        }
                        result &= related;
                    }
                }
                返回 result;
            }

            函数 isWeakType(类型: 类型_): 真假 {
                如果 (是指针类型(类型)) {
                    类型 = 类型.基础类型
                }
                如果 (类型.标志 & 类型标志_.对象_) {
                    常量 resolved = resolveStructuredTypeMembers(<结构类型_>类型);
                    返回 !!(resolved.调用签名组 && resolved.调用签名组.长度 === 0 && resolved.属性组.长度 === 0);
                }
                返回 为假;
            }

            函数 hasCommonProperties(source: 类型_, 目标: 类型_) {
                目标
                循环 (常量 prop 属于 getPropertiesOfType(source)) {
                    返回 prop;
                }
                返回 为假;
            }

            函数 propertiesIdenticalTo(source: 类型_, 目标: 类型_): Ternary {
                如果 (!(source.标志 & 类型标志_.对象_ && 目标.标志 & 类型标志_.对象_)) {
                    返回 Ternary.假_;
                }
                常量 sourceProperties = getPropertiesOfObjectType(source);
                常量 targetProperties = getPropertiesOfObjectType(目标);
                如果 (sourceProperties.长度 !== targetProperties.长度) {
                    返回 Ternary.假_;
                }
                变量 result = Ternary.真_;
                循环 (常量 sourceProp 属于 sourceProperties) {
                    常量 targetProp = getPropertyOfObjectType(目标, sourceProp.名称);
                    如果 (!targetProp) {
                        返回 Ternary.假_;
                    }
                    常量 related = compareProperties(sourceProp, targetProp, isRelatedTo);
                    如果 (!related) {
                        返回 Ternary.假_;
                    }
                    result &= related;
                }
                返回 result;
            }

            函数 signaturesRelatedTo(source: 类型_, target: 类型_, reportErrors: 真假): Ternary {
                如果 (relation === 身份关系) {
                    返回 signaturesIdenticalTo(source, target);
                }

                常量 sourceSignatures = getSignaturesOfType(source);
                常量 targetSignatures = getSignaturesOfType(target);                

                变量 result = Ternary.真_;
                常量 saveErrorInfo = errorInfo;

                如果 (sourceSignatures.长度 === 1 && targetSignatures.长度 === 1) {
                    // For simple functions (functions with a single signature) we only erase 类型 parameters for
                    // the comparable relation. Otherwise, 如果 the source signature is generic, we instantiate it
                    // in the context of the target signature before checking the relationship. Ideally we'd do
                    // this regardless of the number of signatures, but the potential costs are prohibitive due
                    // to the quadratic nature of the logic below.
                    常量 eraseGenerics = relation === 可比较关系;
                    result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors);
                }
                否则 {
                    outer: 循环 (常量 t 属于 targetSignatures) {
                        // Only elaborate errors from the first failure
                        变量 shouldElaborateErrors = reportErrors;
                        循环 (常量 s 属于 sourceSignatures) {
                            常量 related = signatureRelatedTo(s, t, /*erase*/ 为真, shouldElaborateErrors);
                            如果 (related) {
                                result &= related;
                                errorInfo = saveErrorInfo;
                                继续 outer;
                            }
                            shouldElaborateErrors = 为假;
                        }

                        如果 (shouldElaborateErrors) {
                            reportError(诊断信息_.Type_0_provides_no_match_for_the_signature_1,
                                `typeToString(source)`,
                                `signatureToString(t, /*enclosingDeclaration*/ 未定, /*标志*/ 未定, 种类)`);
                        }
                        返回 Ternary.假_;
                    }
                }
                返回 result;
            }

            /**
             * See signatureAssignableTo, compareSignaturesIdentical
             */
            函数 signatureRelatedTo(source: 签名_, target: 签名_, erase: 真假, reportErrors: 真假): Ternary {
                返回 compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target,
                    CallbackCheck.None, /*ignoreReturnTypes*/ 为假, reportErrors, reportError, isRelatedTo);
            }

            函数 signaturesIdenticalTo(source: 类型_, target: 类型_): Ternary {
                常量 sourceSignatures = getSignaturesOfType(source);
                常量 targetSignatures = getSignaturesOfType(target);
                如果 (sourceSignatures.长度 !== targetSignatures.长度) {
                    返回 Ternary.假_;
                }
                变量 result = Ternary.真_;
                循环 (变量 i = 0; i < sourceSignatures.长度; i++) {
                    常量 related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ 为假, /*ignoreThisTypes*/ 为假, /*ignoreReturnTypes*/ 为假, isRelatedTo);
                    如果 (!related) {
                        返回 Ternary.假_;
                    }
                    result &= related;
                }
                返回 result;
            }
        }
        
        函数 getErasedSignature(signature: 签名_): 签名_ {
            返回 signature.typeParameters ?
                signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) :
                signature;
        }
        
        函数 createErasedSignature(signature: 签名_) {
            // Create an instantiation of the signature where all 类型 arguments are the any 类型.
            返回 instantiateSignature(signature, createTypeEraser(signature.typeParameters!), /*eraseTypeParameters*/ 为真);
        }

        函数 是数字类型(t: 类型_): t 作为 数字类型_ {
            返回 !!(t.标志 & 类型标志_.数字类型_)
        }

        函数 整数范围(t: 类型_, 级别: 8 | 16 | 32 | 64) {
            如果 (是数字类型(t)) {
                变量 标志 = t.数字标志
                假如 (级别) {
                    若是 8:
                        返回 !!(标志 & 数字标志_.整数8_)
                    若是 16:
                        返回 !!(标志 & 数字标志_.整数8_) || !!(标志 & 数字标志_.整数16_)
                    若是 32:
                        返回 !!(标志 & 数字标志_.整数8_) || !!(标志 & 数字标志_.整数16_) || !!(标志 & 数字标志_.整数32_)
                    若是 64:
                        返回 !!(标志 & 数字标志_.整数8_) || !!(标志 & 数字标志_.整数16_) || !!(标志 & 数字标志_.整数32_) || !!(标志 & 数字标志_.整数64_)
                }
            }
            返回 为假
        }

        函数 正整数范围(t: 类型_, 级别: 8 | 16 | 32 | 64) {
            如果 (是数字类型(t)) {
                变量 标志 = t.数字标志
                假如 (级别) {
                    若是 8:
                        返回 !!(标志 & 数字标志_.正整数8_)
                    若是 16:
                        返回 !!(标志 & 数字标志_.正整数8_) || !!(标志 & 数字标志_.正整数16_)
                    若是 32:
                        返回 !!(标志 & 数字标志_.正整数8_) || !!(标志 & 数字标志_.正整数16_) || !!(标志 & 数字标志_.正整数32_)
                    若是 64:
                        返回 !!(标志 & 数字标志_.正整数8_) || !!(标志 & 数字标志_.正整数16_) || !!(标志 & 数字标志_.正整数32_) || !!(标志 & 数字标志_.正整数64_)
                }
            }
            返回 为假
        }

        函数 小数范围(t: 类型_, 级别: 32 | 64) {
            如果 (是数字类型(t)) {
                变量 标志 = t.数字标志
                假如 (级别) {
                    若是 32:
                        返回 !!(标志 & 数字标志_.小数32_) || 正整数范围(t, 32) || 整数范围(t, 32)
                    若是 64:
                        返回 !!(标志 & 数字标志_.小数32_) || !!(标志 & 数字标志_.小数64_) || 正整数范围(t, 64) || 整数范围(t, 64)
                }
            }
            返回 为假
        }

        函数 isSimpleTypeRelatedTo(源头: 类型_, 目标: 类型_, 身份: 词典_<关系比较结果_>) {
            如果 (源头 === 目标) 返回 为真
            如果 ((身份 === 可赋值关系 || 身份 === 绝对可以赋值关系) && 目标.标志 & 类型标志_.通用_) 返回 为真;
            如果 (是数组类型(源头) && 是数组类型(目标) && 源头.长度 === 目标.长度 && compareTypesIdentical(源头.基础类型, 目标.基础类型)) 返回 为真
            如果 (是列表类型(源头) && 是列表类型(目标) && compareTypesIdentical(源头.基础类型, 目标.基础类型)) 返回 为真
            如果 (目标.标志 & 类型标志_.文本类型_ && 是数组类型(源头) && compareTypesIdentical(源头.基础类型, 字符类型)) 返回 为真
            如果 (目标.标志 & 类型标志_.真假类型_ && (源头.标志 & 类型标志_.真类型_ || 源头.标志 & 类型标志_.假类型_)) 返回 为真
            如果 (是数字类型(源头) && 是数字类型(目标)) {
                如果 (目标.数字标志 & 数字标志_.整数8_ && 整数范围(源头, 8)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.整数16_ && 整数范围(源头, 16)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.整数32_ && 整数范围(源头, 32)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.整数64_ && 整数范围(源头, 64)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.正整数8_ && 正整数范围(源头, 8)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.正整数16_ && 正整数范围(源头, 16)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.正整数32_ && 正整数范围(源头, 32)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.正整数64_ && 正整数范围(源头, 64)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.小数32_ && 小数范围(源头, 32)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.小数64_ && 小数范围(源头, 64)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.复数64_ && (小数范围(源头, 32) || 源头.数字标志 & 数字标志_.虚数32_)) 返回 为真
                如果 (目标.数字标志 & 数字标志_.复数128_ && (小数范围(源头, 64) || 源头.数字标志 & 数字标志_.虚数64_)) 返回 为真
            }
            返回 为假;
        }

        函数 getUnmatchedProperty(source: 类型_, 目标: 类型_) {
            目标
            source
            常量 properties = getPropertiesOfObjectType(目标);
            循环 (常量 targetProp 属于 properties) {
                常量 sourceProp = getPropertyOfType(source, targetProp.名称);
                如果 (!sourceProp) {
                    返回 targetProp;
                }
            }

            返回 未定;
        }

        函数 getRelationKey(source: 类型_, 目标: 类型_, relation: 词典_<关系比较结果_>) {
            如果 (relation === 身份关系 && source.id > 目标.id) {
                常量 temp = source;
                source = 目标;
                目标 = temp;
            }
            返回 source.id + "," + 目标.id;
        }

        函数 isTypeAssignableToKind(source: 类型_, 种类: 类型标志_, strict?: 真假): 真假 {
            如果 (source.标志 & 种类) {
                返回 为真;
            }
            如果 (strict && source.标志 & (类型标志_.通用_ | 类型标志_.无值_ | 类型标志_.未定_)) {
                返回 为假;
            }
            返回 !!(种类 & 类型标志_.数字类型_ && isTypeAssignableTo(source, 整数类型)) ||
                !!(种类 & 类型标志_.文本类型_ && isTypeAssignableTo(source, 文本类型)) ||
                !!(种类 & 类型标志_.真假类型_ && isTypeAssignableTo(source, 真假类型)) ||
                !!(种类 & 类型标志_.无值_ && isTypeAssignableTo(source, 无值类型)) ||
                !!(种类 & 类型标志_.未定_ && isTypeAssignableTo(source, 未定类型));
        }



        函数 getTypeFactsOfTypes(types: 类型_[]): TypeFacts {
            变量 result: TypeFacts = TypeFacts.None;
            循环 (常量 t 属于 types) {
                result |= getTypeFacts(t);
            }
            返回 result;
        }

        函数 getTypeFacts(类型: 类型_): TypeFacts {
            常量 标志 = 类型.标志;
            如果 (标志 & 类型标志_.文本类型_) {
                返回 TypeFacts.StringFacts;
            }
            如果 (标志 & (类型标志_.数字类型_)) {
                返回 TypeFacts.NumberFacts;
            }
            如果 (标志 & 类型标志_.真假类型_) {
                返回 TypeFacts.BooleanFacts;
            }
            如果 (标志 & (类型标志_.真类型_ | 类型标志_.假类型_)) {
                返回 类型 === 假类型 ? TypeFacts.FalseStrictFacts : TypeFacts.TrueStrictFacts
            }
            如果 (标志 & (类型标志_.未定_ | 类型标志_.无值_)) {
                返回 TypeFacts.UndefinedFacts;
            }
            如果 (标志 & 类型标志_.类型参数_) {
                返回 getTypeFacts(getBaseConstraintOfType(类型) || 通用类型);
            }
            如果 (标志 & (类型标志_.联合_ | 类型标志_.交叉_)) {
                返回 getTypeFactsOfTypes((<联合或交叉类型_>类型).类型组);
            }
            返回 TypeFacts.All;
        }


        函数 isTypeEqualityComparableTo(source: 类型_, 目标: 类型_) {
            返回 (目标.标志 & 类型标志_.未定_) !== 0 || isTypeComparableTo(source, 目标);
        }

        函数 getTypeOfPropertyOfType(类型: 类型_, name: 文字): 类型_ {
            常量 prop = getPropertyOfType(类型, name);
            返回 prop ? getTypeOfSymbol(prop) : 未定!;
        }

        函数 symbolIsValue(符号: 符号_): 真假 {
            返回 !!(符号.标志 & 符号标志_.值_ || 符号.标志 & 符号标志_.别名_ && resolveAlias(符号).标志 & 符号标志_.值_);
        }

        函数 getPropertiesOfType(类型: 类型_): 符号_[] {
            类型 = getApparentType(类型);
            返回 类型.标志 & 类型标志_.联合_ ?
                未定! : getPropertiesOfObjectType(类型);
        }

        函数 getPropertyOfType(类型: 类型_, name: 文字): 符号_ | 未定 {
            如果 (是指针类型(类型)) {
                类型 = 类型.基础类型
            }
            类型 = getApparentType(类型);
            如果 (类型.标志 & 类型标志_.对象_) {
                常量 resolved = resolveStructuredTypeMembers(<对象类型_>类型);
                变量 符号 = resolved.成员.获取(name);
                如果 (!符号 && resolved.方法组) {
                    符号 = resolved.方法组.获取(name);
                }
                返回 符号;
            }

            如果 (类型.标志 & (类型标志_.联合_ | 类型标志_.交叉_)) {
                返回 getPropertyOfUnionOrIntersectionType(<联合或交叉类型_>类型, name);
            }
            返回 未定;
        }

        函数 getPropertyOfUnionOrIntersectionType(类型: 联合或交叉类型_, name: 文字): 符号_ | 未定 {
            变量 property = getUnionOrIntersectionProperty(类型, name);
            返回 property && !(getCheckFlags(property) & CheckFlags.Partial) ? property : 未定;
        }

        函数 getPropertiesOfObjectType(类型: 类型_): 符号_[] {
            如果 (是指针类型(类型)) {
                类型 = 类型.基础类型
            }
            如果 (类型.标志 & 类型标志_.对象_) {
                返回 resolveStructuredTypeMembers(<对象类型_>类型).属性组;
            }
            返回 空数组;
        }

        函数 getPropertyOfObjectType(类型: 类型_, name: 文字): 符号_ | 未定 {
            如果 (是指针类型(类型)) {
                类型 = 类型.基础类型
            }
            如果 (类型.标志 & 类型标志_.对象_) {
                常量 resolved = resolveStructuredTypeMembers(<结构类型_>类型);
                常量 符号 = resolved.成员.获取(name);
                如果 (符号 && symbolIsValue(符号)) {
                    返回 符号;
                }
            }
        }

        函数 getNumParametersToCheckForSignatureRelatability(source: 签名_, 源非剩余参数数量: 数字, 目标: 签名_, 目标非剩余参数数量: 数字) {
            如果 (source.具有剩余参数 === 目标.具有剩余参数) {
                如果 (source.具有剩余参数) {
                    // If both have rest parameters, get the max and add 1 to
                    // compensate for the rest parameter.
                    返回 数学_.max(源非剩余参数数量, 目标非剩余参数数量) + 1;
                }
                否则 {
                    返回 数学_.min(源非剩余参数数量, 目标非剩余参数数量);
                }
            }
            否则 {
                // Return the count for whichever signature doesn't have rest parameters.
                返回 source.具有剩余参数 ? 目标非剩余参数数量 : 源非剩余参数数量;
            }
        }

        函数 isEmptyResolvedType(t: 解析类型_) {
            返回 t.属性组.长度 === 0 && !!t.调用签名组 && t.调用签名组.长度 === 0
        }

        函数 isEmptyObjectType(类型: 类型_): 真假 {
            返回 类型.标志 & 类型标志_.对象_ ? isEmptyResolvedType(resolveStructuredTypeMembers(<结构类型_>类型)) :
                类型.标志 & 类型标志_.联合_ ? !!循环执行((<联合类型_>类型).类型组, isEmptyObjectType) : 为假;
        }

        函数 getTypeOfParameter(符号: 符号_) {
            返回 getTypeOfSymbol(符号);
        }

        函数 getTypeOfSymbol(符号: 符号_): 类型_ {
            如果 (getCheckFlags(符号) & CheckFlags.Instantiated) {
                返回 getTypeOfInstantiatedSymbol(符号);
            }
            如果 (符号.标志 & (符号标志_.变量_ | 符号标志_.属性_)) {
                返回 getTypeOfVariableOrParameterOrProperty(符号);
            }
            如果 (符号.标志 & (符号标志_.函数_ | 符号标志_.方法_ | 符号标志_.枚举_)) {
                返回 getTypeOfFuncClassEnumModule(符号);
            }
            如果 (符号.标志 & 符号标志_.枚举成员_) {
                返回 获取枚举成员类型(符号);
            }
            如果(符号.标志& 符号标志_.程序_){
                返回 获取程序声明的类型(getMergedSymbol(符号))
            }
            如果 (符号.标志 & 符号标志_.别名_) {
                返回 getTypeOfAlias(符号);
            }
            返回 未知类型;
        }

        函数 getTypeOfInstantiatedSymbol(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.类型) {
                如果 (symbolInstantiationDepth === 100) {
                    error(符号.值声明, 诊断信息_.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite);
                    links.类型 = 未知类型;
                }
                否则 {
                    如果 (!pushTypeResolution(符号, 类型系统属性名称_.类型_)) {
                        返回 未知类型;
                    }
                    symbolInstantiationDepth++;
                    变量 类型 = instantiateType(getTypeOfSymbol(links.目标!), links.映射!);
                    symbolInstantiationDepth--;
                    如果 (!popTypeResolution()) {
                        类型 = reportCircularityError(符号);
                    }
                    links.类型 = 类型;
                }
            }
            返回 links.类型;
        }

        函数 getTypeOfAlias(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.类型) {
                常量 targetSymbol = resolveAlias(符号);
                links.类型 = targetSymbol.标志 & 符号标志_.值_
                    ? getTypeOfSymbol(targetSymbol)
                    : 未知类型;
            }
            返回 links.类型;
        }

        函数 getTypeOfFuncClassEnumModule(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.类型) {
                links.类型 = 创建对象类型(对象标志_.匿名_, 符号);
            }
            返回 links.类型!;
        }

        函数 getSingleCallSignature(类型: 类型_): 签名_ {
            如果 (是指针类型(类型)) {
                类型 = 类型.基础类型
            }
            如果 (类型.标志 & 类型标志_.对象_) {
                常量 resolved = resolveStructuredTypeMembers(<结构类型_>类型);
                如果 (resolved.调用签名组 && resolved.调用签名组.长度 && resolved.调用签名组.长度 === 1 && (!resolved.属性组 || resolved.属性组.长度 === 0)) {
                    返回 resolved.调用签名组[0];
                }
            }
            返回 未定!;
        }

        函数 getRestTypeOfSignature(signature: 签名_): 类型_ {
            如果 (signature.具有剩余参数) {
                常量 类型 = getTypeOfSymbol(最后或未定义(signature.参数)!);
                返回 类型
            }
            返回 通用类型;
        }

        函数 symbolToString(符号: 符号_): 文字 {
            返回 符号.名称
        }

        函数 resolveTypeReferenceName(typeReferenceName: 实体名或实体名表达式_, meaning: 符号标志_) {
            返回 resolveEntityName(typeReferenceName, meaning) || 未知符号;
        }

        函数 getTypeReferenceType(n: 类型引用节点_ | 表达式包括类型参数_, 符号: 符号_) {
            如果 (符号.标志 & (符号标志_.类型别名_ | 符号标志_.类型声明_)) {
                返回 getTypeFromTypeAliasReference(n, 符号);
            }
            如果 (符号.标志 & 符号标志_.结构_) {
                返回 获取结构类型实例类型(n, 符号);
            }
            如果 (符号.标志 & 符号标志_.接口_) {
                返回 获取接口类型实例类型(n, 符号);
            }
            常量 res = tryGetDeclaredTypeOfSymbol(符号);
            如果 (res) {
                返回 checkNoTypeArguments(n, 符号) ? res : 未知类型
            }
            返回 未知类型
        }

        函数 获取接口类型实例类型(n: 类型引用节点_ | 表达式包括类型参数_, 符号: 符号_) {
            常量 类型 = getDeclaredTypeOfSymbol(符号);
            常量 typeParameters = (<接口类型_>类型).类型参数 || getSymbolLinks(符号).类型参数
            如果 (typeParameters) {
                常量 typeArguments = typeArgumentsFromTypeReferenceNode(n)!
                常量 minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                返回 createTypeReference(<泛型类型_>类型, fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount));
            }
            返回 checkNoTypeArguments(n, 符号) ? 类型 : 未知类型;
        }

        函数 获取结构类型实例类型(n: 类型引用节点_ | 表达式包括类型参数_, 符号: 符号_) {
            常量 类型 = getDeclaredTypeOfSymbol(符号);
            常量 typeParameters = (<结构类型_>类型).类型参数 || getSymbolLinks(符号).类型参数
            如果 (typeParameters) {
                常量 typeArguments = typeArgumentsFromTypeReferenceNode(n)!
                常量 minTypeArgumentCount = getMinTypeArgumentCount(typeParameters);
                返回 createTypeReference(<泛型类型_>类型, fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount));
            }
            返回 checkNoTypeArguments(n, 符号) ? 类型 : 未知类型;
        }

        函数 getTypeFromTypeAliasReference(n: 类型引用节点_ | 表达式包括类型参数_, 符号: 符号_) {
            常量 类型 = getDeclaredTypeOfSymbol(符号);
            常量 typeParameters = getSymbolLinks(符号).类型参数
            如果 (typeParameters) {
                返回 getTypeAliasInstantiation(符号, typeArgumentsFromTypeReferenceNode(n))
            }
            返回 checkNoTypeArguments(n, 符号) ? 类型 : 未知类型;
        }

        函数 checkNoTypeArguments(node: 类型引用节点_ | 表达式包括类型参数_, 符号?: 符号_) {
            符号
            如果 (node.类型实参) {
                error(node, 诊断信息_.Type_0_is_not_generic, `符号 ? symbolToString(符号) : (<类型引用节点_>node).类型名 ? declarationNameToString((<类型引用节点_>node).类型名) : "(anonymous)"`);
                返回 为假;
            }
            返回 为真;
        }

        函数 typeArgumentsFromTypeReferenceNode(node: 类型引用节点_ | 表达式包括类型参数_): 类型_[] | 未定 {
            返回 词典(node.类型实参!, getTypeFromTypeNode);
        }

        函数 getTypeAliasInstantiation(符号: 符号_, typeArguments: 只读数组_<类型_> | 未定): 类型_ {
            常量 类型 = getDeclaredTypeOfSymbol(符号);
            常量 links = getSymbolLinks(符号);
            常量 typeParameters = links.类型参数!;
            常量 id = getTypeListId(typeArguments);
            变量 instantiation = links.instantiations!.获取(id);
            如果 (!instantiation) {
                links.instantiations!.设置(id, instantiation = instantiateType(类型, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments!, typeParameters!, getMinTypeArgumentCount(typeParameters)))));
            }
            返回 instantiation;
        }

        函数 getMinTypeArgumentCount(typeParameters: 只读数组_<类型参数_> | 未定): 数字 {
            变量 minTypeArgumentCount = 0;
            如果 (typeParameters) {
                循环 (变量 i = 0; i < typeParameters.长度; i++) {
                    如果 (!hasTypeParameterDefault(typeParameters[i])) {
                        minTypeArgumentCount = i + 1;
                    }
                }
            }
            返回 minTypeArgumentCount;
        }

        函数 hasTypeParameterDefault(typeParameter: 类型参数_): 真假 {
            返回 !!(typeParameter.符号 && 循环执行(typeParameter.符号.声明组, decl => isTypeParameterDeclaration(decl) && (decl.默认 || decl.可选)));
        }

        /**
         * Fill in default types for unsupplied 类型 arguments. If `typeArguments` is 未定
         * when a default 类型 is supplied, a new array will be created and returned.
         *
         * @param typeArguments The supplied 类型 arguments.
         * @param typeParameters The requested 类型 parameters.
         * @param minTypeArgumentCount The minimum number of required 类型 arguments.
         */
        函数 fillMissingTypeArguments(typeArguments: 只读数组_<类型_>, typeParameters: 只读数组_<类型参数_> | 未定, minTypeArgumentCount: 数字): 类型_[];
        函数 fillMissingTypeArguments(typeArguments: 只读数组_<类型_> | 未定, typeParameters: 只读数组_<类型参数_> | 未定, minTypeArgumentCount: 数字): 类型_[] | 未定;
        函数 fillMissingTypeArguments(typeArguments: 只读数组_<类型_> | 未定, typeParameters: 只读数组_<类型参数_> | 未定, minTypeArgumentCount: 数字) {
            常量 numTypeParameters = 长度(typeParameters!);
            如果 (!numTypeParameters) {
                返回 [];
            }
            常量 numTypeArguments = 长度(typeArguments!);
            如果 (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters) {
                常量 result = typeArguments ? typeArguments.分切() : [];
                // Map invalid forward references in default types to the error 类型
                循环 (变量 i = numTypeArguments; i < numTypeParameters; i++) {
                    result[i] = 未知类型;
                }
                常量 baseDefaultType = 通用类型;
                循环 (变量 i = numTypeArguments; i < numTypeParameters; i++) {
                    变量 defaultType = getDefaultFromTypeParameter(typeParameters![i]);
                    result[i] = defaultType ? instantiateType(defaultType, createTypeMapper(typeParameters!, result)) : baseDefaultType;
                }
                result.长度 = typeParameters!.长度;
                返回 result;
            }
            返回 typeArguments && typeArguments.分切();
        }

        函数 获取接口的声明类型(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                如果 (!pushTypeResolution(符号, 类型系统属性名称_.声明的类型_)) {
                    返回 未知类型;
                }
                变量 类型 = links.declaredType = <接口类型_>创建对象类型(对象标志_.接口_, 符号)
                如果 (popTypeResolution()) {
                    常量 typeParameters = 获取类型的本地类型参数(符号);
                    如果 (typeParameters) {
                        类型.对象标志 |= 对象标志_.引用_
                        // Initialize the instantiation cache for generic 类型 aliases. The declared 类型 corresponds to
                        // an instantiation of the 类型 alias with the 类型 parameters supplied as 类型 arguments.
                        类型.类型参数 = typeParameters;
                        (<泛型类型_>类型).instantiations = 创建词典<类型引用_>();
                        (<泛型类型_>类型).instantiations.设置(getTypeListId(typeParameters), <泛型类型_>类型);
                        (<泛型类型_>类型).类型实参 = 类型.类型参数;
                        (<泛型类型_>类型).目标 = <泛型类型_>类型
                        类型.thisType = createTypeParameter(符号);
                        类型.thisType.isThisType = 为真;
                        类型.thisType.约束 = 类型;
                    }
                }
            }
            返回 links.declaredType!
        }

        函数 获取结构的声明类型(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                如果 (!pushTypeResolution(符号, 类型系统属性名称_.声明的类型_)) {
                    返回 未知类型;
                }
                变量 类型 = links.declaredType = <结构类型_>创建对象类型(对象标志_.结构_, 符号)
                如果 (popTypeResolution()) {
                    常量 typeParameters = 获取类型的本地类型参数(符号);
                    如果 (typeParameters) {
                        类型.对象标志 |= 对象标志_.引用_
                        // Initialize the instantiation cache for generic 类型 aliases. The declared 类型 corresponds to
                        // an instantiation of the 类型 alias with the 类型 parameters supplied as 类型 arguments.
                        类型.类型参数 = typeParameters;
                        (<泛型类型_>类型).instantiations = 创建词典<类型引用_>();
                        (<泛型类型_>类型).instantiations.设置(getTypeListId(typeParameters), <泛型类型_>类型);
                        (<泛型类型_>类型).类型实参 = 类型.类型参数;
                        (<泛型类型_>类型).目标 = <泛型类型_>类型
                        类型.thisType = createTypeParameter(符号);
                        类型.thisType.isThisType = 为真;
                        类型.thisType.约束 = 类型;
                    }
                }
            }
            返回 links.declaredType!
        }

        函数 createTypeParameter(符号?: 符号_) {
            常量 类型 = <类型参数_>创建类型(类型标志_.类型参数_);
            如果 (符号) 类型.符号 = 符号;
            返回 类型;
        }

        函数 获取类型别名的声明类型(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                如果 (!pushTypeResolution(符号, 类型系统属性名称_.声明的类型_)) {
                    返回 未知类型;
                }
                常量 _声明 = 查找(符号.声明组!, 是类型别名声明)!
                变量 类型 = getTypeFromTypeNode(_声明.类型)
                如果 (popTypeResolution()) {
                    常量 typeParameters = 获取类型的本地类型参数(符号);
                    如果 (typeParameters) {
                        // Initialize the instantiation cache for generic 类型 aliases. The declared 类型 corresponds to
                        // an instantiation of the 类型 alias with the 类型 parameters supplied as 类型 arguments.
                        links.类型参数 = typeParameters;
                        links.instantiations = 创建词典<类型_>();
                        links.instantiations.设置(getTypeListId(typeParameters), 类型);
                    }
                }
                否则 {
                    类型 = 未知类型;
                    error(_声明.名称, 诊断信息_.Type_alias_0_circularly_references_itself, `symbolToString(符号)`);
                }
                links.declaredType = 类型
            }
            返回 links.declaredType!
        }

        函数 获取类型声明的声明类型(符号: 符号_): 类型_ | 未定 {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                如果 (!pushTypeResolution(符号, 类型系统属性名称_.声明的类型_)) {
                    返回 未知类型;
                }
                常量 _声明 = 查找(符号.声明组!, 是类型声明)!
                变量 声明类型 = getTypeFromTypeNode(_声明.类型)
                变量 定义的类型 = <定义类型_>创建对象类型(对象标志_.定义_, 符号)
                如果 (popTypeResolution()) {
                    常量 typeParameters = 获取类型的本地类型参数(符号);
                    如果 (typeParameters) {
                        // Initialize the instantiation cache for generic 类型 aliases. The declared 类型 corresponds to
                        // an instantiation of the 类型 alias with the 类型 parameters supplied as 类型 arguments.
                        links.类型参数 = typeParameters;
                        links.instantiations = 创建词典<类型_>();
                        links.instantiations.设置(getTypeListId(typeParameters), 声明类型);
                    }
                }
                否则 {
                    声明类型 = 未知类型;
                    error(_声明.名称, 诊断信息_.Type_alias_0_circularly_references_itself, `symbolToString(符号)`);
                }
                定义的类型.基础类型 = 声明类型
                links.declaredType = 定义的类型
            }
            返回 links.declaredType
        }

        函数 getTypeFromTypeReference(node: 类型引用节点_ | 表达式包括类型参数_): 类型_ {
            常量 links = getNodeLinks(node);
            如果 (!links.resolvedType) {
                变量 符号: 符号_;
                变量 类型: 类型_;
                变量 meaning = 符号标志_.类型_;
                如果 (!类型!) {
                    符号 = resolveTypeReferenceName(getTypeReferenceName(node)!, meaning);
                    类型 = getTypeReferenceType(node, 符号);
                }
                // Cache both the resolved 符号 and the resolved 类型. The resolved 符号 is needed in when we check the
                // 类型 reference in checkTypeReferenceNode.
                links.解析的符号 = 符号!;
                links.resolvedType = 类型!;
            }
            返回 links.resolvedType;
        }

        函数 getTypeReferenceName(node: 类型引用节点_ | 表达式包括类型参数_): 实体名或实体名表达式_ | 未定 {
            如果(是指针类型节点(node)){
                node = node.基础类型 转为 类型引用节点_
            }
            假如 (node.种类) {
                若是 语法_.类型引用_:
                    返回 node.类型名;
                若是 语法_.表达式包括类型参数_:
                    // We only support expressions that are simple qualified names. For other
                    // expressions this produces 未定.
                    常量 expr = node.表达式;
                    如果 (是实体名称表达式(expr)) {
                        返回 expr;
                    }
                // fall through;
            }

            返回 未定;
        }
        // 种类 如果 at least one constituent 类型 is of the given 种类.
        函数 maybeTypeOfKind(类型: 类型_, 种类: 类型标志_): 真假 {
            如果 (类型.标志 & 种类) {
                返回 为真;
            }
            如果 (类型.标志 & (类型标志_.联合_ | 类型标志_.交叉_)) {
                常量 types = (<联合或交叉类型_>类型).类型组;
                循环 (常量 t 属于 types) {
                    如果 (maybeTypeOfKind(t, 种类)) {
                        返回 为真;
                    }
                }
            }
            返回 为假;
        }

        函数 createInstantiatedSymbolTable(symbols: 符号_[], 映射: 类型映射_): 符号表_ {
            常量 result = 创建符号表();
            循环 (常量 符号 属于 symbols) {
                result.设置(符号.名称, instantiateSymbol(符号, 映射));
            }
            返回 result;
        }

        函数 instantiateSymbol(符号: 符号_, 映射: 类型映射_): 符号_ {
            常量 links = getSymbolLinks(符号);
            如果 (links.类型 && !maybeTypeOfKind(links.类型, 类型标志_.对象_ | 类型标志_.类型参数_)) {
                // If the 类型 of the 符号 is already resolved, and 如果 that 类型 could not possibly
                // be affected by instantiation, simply 返回 the 符号 itself.
                返回 符号;
            }
            如果 (getCheckFlags(符号) & CheckFlags.Instantiated) {
                // If 符号 being instantiated is itself a instantiation, fetch the original 目标 and combine the
                // 类型 mappers. This ensures that original 类型 identities are properly preserved and that aliases
                // always reference a non-aliases.
                符号 = links.目标!;
                映射 = combineTypeMappers(links.映射!, 映射);
            }
            // Keep the 标志 from the 符号 we're instantiating.  Mark that is instantiated, and
            // also transient so that we can just store data on it directly.
            常量 result = createSymbol(符号.标志, 符号.名称, CheckFlags.Instantiated  | getCheckFlags(符号) & (CheckFlags.RestParameter));
            result.声明组 = 符号.声明组;
            result.父符号 = 符号.父符号;
            result.目标 = 符号;
            result.映射 = 映射;
            如果 (符号.值声明) {
                result.值声明 = 符号.值声明;
            }
            返回 result;
        }

        函数 getTypeFromTypeNode(n: 类型节点_): 类型_ {
            假如 (n.种类) {
                若是 语法_.通用_:
                    返回 通用类型
                若是 语法_.无值_:
                    返回 无值类型
                若是 语法_.文本_:
                    返回 文本类型
                若是 语法_.指针_:
                    返回 无符号指针类型
                若是 语法_.整数_:
                    返回 整数类型
                若是 语法_.整数8_:
                    返回 整数类型_8
                若是 语法_.整数16_:
                    返回 整数类型_16
                若是 语法_.整数32_:
                    返回 整数类型_32
                若是 语法_.整数64_:
                    返回 整数类型_64
                若是 语法_.正整数_:
                    返回 正整数类型
                若是 语法_.正整数8_:
                    返回 正整数类型_8
                若是 语法_.正整数16_:
                    返回 正整数类型_16
                若是 语法_.正整数32_:
                    返回 正整数类型_32
                若是 语法_.正整数64_:
                    返回 正整数类型_64
                若是 语法_.小数_:
                    返回 小数类型
                若是 语法_.小数32_:
                    返回 小数类型_32
                若是 语法_.小数64_:
                    返回 小数类型_64
                若是 语法_.复数64_:
                    返回 复数类型_64
                若是 语法_.复数128_:
                    返回 复数类型_128
                若是 语法_.真_:
                    返回 真类型
                若是 语法_.假_:
                    返回 假类型
                若是 语法_.真假_:
                    返回 真假类型
                若是 语法_.字节_:
                    返回 字节类型
                若是 语法_.字符_:
                    返回 字符类型
                若是 语法_.未定_:
                    返回 未定类型
                若是 语法_.括号类型_:
                    返回 getTypeFromTypeNode((<括号类型节点_>n).类型)
                若是 语法_.指针类型_:
                    返回 创建指针类型(getTypeFromTypeNode((<指针类型节点_>n).基础类型))
                若是 语法_.列表类型_:
                    返回 创建列表类型(getTypeFromTypeNode((<列表类型节点_>n).元素类型), 未定!, 未定!)
                若是 语法_.数组类型_: {
                    如果 (!(<数组类型节点_>n).长度) {
                        返回 创建数组类型(getTypeFromTypeNode((<数组类型节点_>n).元素类型), 未定)
                    }
                    变量 长度 = 计算常量值((<数组类型节点_>n).长度!)
                    如果 (类为 长度 === "数字") {
                        返回 创建数组类型(getTypeFromTypeNode((<数组类型节点_>n).元素类型), 长度)
                    }
                    error(n, 诊断信息_.数组长度必须为数字字面量或数字结果的常量表达式或可根据表达式推断)
                    返回 未知类型
                }
                若是 语法_.词典类型_:
                    返回 创建词典类型(getTypeFromTypeNode((<词典类型节点_>n).键类型), getTypeFromTypeNode((<词典类型节点_>n).值类型))
                若是 语法_.通信类型_:
                    返回 创建通信类型(getTypeFromTypeNode((<通信类型节点_>n).元素类型), 未定!)
                若是 语法_.只读通信_:
                    返回 创建只读通信类型(getTypeFromTypeNode((<只读通信节点_>n).元素类型), 未定!)
                若是 语法_.只写通信_:
                    返回 创建只写通信类型(getTypeFromTypeNode((<只写通信节点_>n).元素类型), 未定!)
                若是 语法_.类型引用_:
                若是 语法_.表达式包括类型参数_:
                    返回 getTypeFromTypeReference(<类型引用节点_ | 表达式包括类型参数_>n)
                若是 语法_.返回值声明属性组_:
                    返回 获取返回值声明属性组类型(<返回值声明属性组_>n)
                若是 语法_.联合类型_:
                    返回 getTypeFromUnionTypeNode(<联合类型节点_>n)
                若是 语法_.交叉类型_:
                    返回 getTypeFromIntersectionTypeNode(<交叉类型节点_>n);
                若是 语法_.函数类型_:
                    返回 getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(<函数类型节点_>n) //getTypeFromTypeNode((<函数类型节点_>node).类型!)
                若是 语法_.变长参数类型_:
                    返回 创建列表类型(getTypeFromTypeNode((<变长参数类型_>n).元素类型), 未定!, 未定!)
                若是 语法_.标识符_:
                若是 语法_.限定名_:
                    常量 符号 = getSymbolAtLocation(n);
                    返回 符号 && getDeclaredTypeOfSymbol(符号) || 未知类型;
                若是 语法_.类型_:
                    返回 创建类型(类型标志_.类型参数_)
                默认:
                    返回 未知类型
            }
        }

        函数 获取返回值声明属性组类型(n: 返回值声明属性组_) {
            变量 父节点 = <函数声明_>n.父节点
            变量 签名 = getSignatureFromDeclaration(父节点)
            返回 签名.resolvedReturnType || 无值类型
        }
        
        函数 getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: 类型节点_): 类型_ {
            常量 links = getNodeLinks(node);
            如果 (!links.resolvedType) {
                // Deferred resolution of members is handled by resolveObjectTypeMembers
                常量 aliasSymbol = getAliasSymbolForTypeNode(node);
                如果 (node.符号.成员 && node.符号.成员.大小=== 0 && !aliasSymbol) {
                    links.resolvedType = emptyTypeLiteralType;
                }
                否则 {
                    变量 类型 = 创建对象类型(对象标志_.匿名_, node.符号);
                    类型.aliasSymbol = aliasSymbol;
                    类型.aliasTypeArguments = getTypeArgumentsForAliasSymbol(aliasSymbol);
                    links.resolvedType = 类型;
                }
            }
            返回 links.resolvedType;
        }

        函数 getTypeArgumentsForAliasSymbol(符号: 符号_ | 未定) {
            返回 符号 ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(符号!) : 未定;
        }

        函数 getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(符号: 符号_): 类型参数_[] | 未定 {
            变量 result: 类型参数_[] | 未定;
            循环 (常量 n 属于 符号.声明组!) {
                如果 (n.种类 === 语法_.接口声明_||
                    n.种类 === 语法_.结构声明_ ||
                    是类型别名声明(n)||
                    是类型声明(n)) {
                        常量 declaration = <接口声明_ | 结构声明_ | 类型别名声明_ | 类型声明_>n;
                    result = appendTypeParameters(result!, getEffectiveTypeParameterDeclarations(declaration!));
                }
            }
            返回 result;
        }
        
        函数 getAliasSymbolForTypeNode(node: 类型节点_) {
            返回 是类型别名声明(node.父节点) || 是类型声明(node.父节点) ? getSymbolOfNode(node.父节点) : 未定;
        }

        函数 获取别名符号从类型别名声明或类型声明节点(tn: 类型节点_) {
            返回 tn.父节点.种类 === 语法_.类型别名声明_ || tn.父节点.种类 === 语法_.类型声明_ ? getSymbolOfNode(tn.父节点) : 未定;
        }

        函数 tryGetTypeFromEffectiveTypeNode(declaration: 声明_) {
            常量 typeNode = getEffectiveTypeAnnotationNode(declaration);
            如果 (typeNode) {
                返回 getTypeFromTypeNode(typeNode);
            }
        }

        函数 getTypeOfVariableOrParameterOrProperty(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.类型) {
                // Handle catch clause variables
                常量 _声明 = 符号.值声明;
                // Handle variable, parameter or property
                如果 (!pushTypeResolution(符号, 类型系统属性名称_.类型_)) {
                    返回 未知类型;
                }

                变量 类型: 类型_;

                如果 (是属性访问表达式(_声明) || 是标识符(_声明) || isMethodDeclaration(_声明) || isMethodSignature(_声明)) {
                    // 符号_ is property of some 种类 that is merged with something - should use `getTypeOfFuncClassEnumModule` and not `getTypeOfVariableOrParameterOrProperty`
                    如果 (符号.标志 & (符号标志_.函数_ | 符号标志_.方法_)) {
                        返回 getTypeOfFuncClassEnumModule(符号);
                    }
                    类型 = tryGetTypeFromEffectiveTypeNode(_声明) || 通用类型;
                }
                否则 如果 (是结构字面量成员表达式(_声明)) {
                    类型 = tryGetTypeFromEffectiveTypeNode(_声明) || checkPropertyAssignment(_声明);
                }
                否则 如果 (isParameter(_声明)
                    || 是属性声明(_声明)
                    || 是变量族(_声明)) {
                    类型 = getWidenedTypeForVariableLikeDeclaration(_声明, /*reportErrors*/ 为真)!;
                }
                否则 如果 (符号.标志 & 符号标志_.属性_) {
                    如果 (是接受者声明(_声明)) {
                        常量 接受者类型符号 = resolveTypeReferenceName(getTypeReferenceName(<类型引用节点_>_声明.类型!)!, 符号标志_.类型_);
                        类型 = getDeclaredTypeOfSymbol(接受者类型符号)
                    }
                }
                否则 {
                    调试_.失败("Unhandled _声明 种类! " + 调试_.显示语法标志(_声明));
                }

                如果 (!popTypeResolution()) {
                    类型 = reportCircularityError(符号);
                }
                links.类型 = 类型!;
            }
            返回 links.类型;
        }
        
        函数 reportErrorsFromWidening(declaration: 声明_, 类型: 类型_) {
            如果 (生产诊断 && 类型.标志 & 类型标志_.ContainsWideningType) {
                // Report implicit any error within 类型 如果 possible, otherwise report error on declaration
                如果 (!reportWideningErrorsInType(类型)) {
                    reportImplicitAnyError(declaration, 类型);
                }
            }
        }        

        函数 reportImplicitAnyError(declaration: 声明_, 类型: 类型_) {
            类型
            常量 typeAsString = `typeToString(getWidenedType(类型))`;
            变量 diagnostic: 诊断信息_;
            假如 (declaration.种类) {
                若是 语法_.属性声明_:
                    diagnostic = 诊断信息_.Member_0_implicitly_has_an_1_type;
                    跳出;
                若是 语法_.参数_:
                    
                    diagnostic = (<参数声明_>declaration).类型 && 是变长参数类型节点((<参数声明_>declaration).类型!) ?
                        诊断信息_.Rest_parameter_0_implicitly_has_an_any_type :
                        诊断信息_.Parameter_0_implicitly_has_an_1_type;
                    跳出;
                若是 语法_.函数声明_:
                若是 语法_.方法声明_:
                若是 语法_.方法签名_:
                若是 语法_.函数表达式_:
                若是 语法_.箭头函数_:
                    如果 (!(declaration 转为 名称声明_).名称) {
                        error(declaration, 诊断信息_.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString);
                        返回;
                    }
                    diagnostic = 诊断信息_._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type;
                    跳出;
                默认:
                    diagnostic = 诊断信息_.Variable_0_implicitly_has_an_1_type;
            }
            error(declaration, diagnostic, `declarationNameToString(getNameOfDeclaration(declaration))`, typeAsString);
        }
        
        函数 reportWideningErrorsInType(类型: 类型_): 真假 {
            变量 errorReported = 为假;
            如果 (类型.标志 & 类型标志_.ContainsWideningType) {
                如果 (类型.标志 & 类型标志_.联合_) {
                    如果 (某些((<联合类型_>类型).类型组, isEmptyObjectType)) {
                        errorReported = 为真;
                    }
                    否则 {
                        循环 (常量 t 属于 (<联合类型_>类型).类型组) {
                            如果 (reportWideningErrorsInType(t)) {
                                errorReported = 为真;
                            }
                        }
                    }
                }
                如果 (isObjectLiteralType(类型)) {
                    循环 (常量 p 属于 getPropertiesOfObjectType(类型)) {
                        常量 t = getTypeOfSymbol(p);
                        如果 (t.标志 & 类型标志_.ContainsWideningType) {
                            如果 (!reportWideningErrorsInType(t)) {
                                error(p.值声明, 诊断信息_.Object_literal_s_property_0_implicitly_has_an_1_type, symbolToString(p), `typeToString(getWidenedType(t))`);
                            }
                            errorReported = 为真;
                        }
                    }
                }
            }
            返回 errorReported;
        }
        
        函数 getWidenedTypeForVariableLikeDeclaration(declaration: 参数声明_ | 属性声明_|  变量族声明_, reportErrors?: 真假): 类型_ | 未定 {
            变量 类型 = getTypeForVariableLikeDeclaration(declaration);
            如果 (类型) {
                如果 (reportErrors) {
                    reportErrorsFromWidening(declaration, 类型);
                }

                返回 getWidenedType(类型);
            }
            返回 类型;
        }
        
        函数 getTypeForVariableLikeDeclaration(declaration: 参数声明_ | 属性声明_|  变量族声明_): 类型_| 未定 {
            常量 declaredType = tryGetTypeFromEffectiveTypeNode(declaration);
            如果 (declaredType) {
                返回 declaredType;
            }

            如果 (declaration.种类 === 语法_.参数_) {
                变量 类型 = getContextuallyTypedParameterType(declaration);
                如果 (类型) {
                    返回 类型;
                }
            }

            // No 类型 specified and nothing can be inferred
            返回 未定!;
        }
        
        // Return contextual 类型 of parameter or undefined 如果 no contextual 类型 is available
        函数 getContextuallyTypedParameterType(parameter: 参数声明_): 类型_ | 未定 {
            常量 func = parameter.父节点;
            如果 (是函数表达式或箭头函数(func)) {
                常量 iife = getImmediatelyInvokedFunctionExpression(func);
                如果 (iife && iife.实参组) {
                    常量 indexOfParameter = func.参数!.indexOf(parameter);
                    常量 links = getNodeLinks(iife);
                    常量 cached = links.resolvedSignature;
                    links.resolvedSignature = 任意签名
                    常量 类型 = indexOfParameter < iife.实参组.长度 ?
                        getWidenedLiteralType(checkExpression(iife.实参组[indexOfParameter])) : 未定;
                    links.resolvedSignature = cached;
                    返回 类型;
                }
                常量 contextualSignature = getContextualSignature(func);
                如果 (contextualSignature) {
                    常量 funcHasRestParameters = 具有剩余参数(func);
                    常量 len = func.参数!.长度 - (funcHasRestParameters ? 1 : 0);
                    变量 indexOfParameter = func.参数!.indexOf(parameter);
                    如果 (indexOfParameter < len) {
                        返回 getTypeAtPosition(contextualSignature, indexOfParameter);
                    }

                    // If last parameter is contextually rest parameter get its 类型
                    如果 (funcHasRestParameters &&
                        indexOfParameter === (func.参数!.长度 - 1) &&
                        isRestParameterIndex(contextualSignature, func.参数!.长度 - 1)) {
                        返回 getTypeOfSymbol(最后或未定义(contextualSignature.参数)!);
                    }
                }
            }
            返回 未定;
        }


        函数 reportCircularityError(符号: 符号_) {
            如果 (getEffectiveTypeAnnotationNode(<变量族声明_>符号.值声明)) {
                error(符号.值声明, 诊断信息_._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation,
                    symbolToString(符号));
                返回 未知类型;
            }
            返回 通用类型;
        }

        函数 getEffectiveTypeAnnotationNode(node: 节点_): 类型节点_ | 未定 {
            返回 (node 转为 任意).类型
        }

        函数 getDeclaredTypeOfSymbol(符号: 符号_): 类型_ {
            返回 tryGetDeclaredTypeOfSymbol(符号) || 通用类型;
        }

        函数 tryGetDeclaredTypeOfSymbol(符号: 符号_): 类型_ | 未定 {
            如果 (符号.标志 & 符号标志_.接口_) {
                返回 获取接口的声明类型(符号);
            }
            如果 (符号.标志 & 符号标志_.结构_) {
                返回 获取结构的声明类型(符号);
            }
            如果 (符号.标志 & 符号标志_.类型声明_) {
                返回 获取类型声明的声明类型(符号)
            }
            如果 (符号.标志 & 符号标志_.类型别名_) {
                返回 获取类型别名的声明类型(符号);
            }
            如果 (符号.标志 & 符号标志_.程序_) {
                返回 获取程序声明的类型(符号)
            }
            如果 (符号.标志 & 符号标志_.类型参数_) {
                返回 getDeclaredTypeOfTypeParameter(符号);
            }
            如果 (符号.标志 & 符号标志_.枚举_) {
                返回 获取枚举类型(符号)
            }
            如果 (符号.标志 & 符号标志_.枚举成员_) {
                返回 获取枚举成员类型(符号)
            }
            如果 (符号.标志 & 符号标志_.别名_) {
                返回 getDeclaredTypeOfAlias(符号)
            }
            返回 未定;
        }

        函数 getDeclaredTypeOfAlias(符号: 符号_): 类型_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(符号));
            }
            返回 links.declaredType;
        }

        函数 获取枚举类型(符号: 符号_) {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                links.declaredType = 创建对象类型(对象标志_.枚举_, 符号)
            }
            返回 links.declaredType!
        }

        函数 获取枚举成员类型(符号: 符号_) {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                如果 (符号.值声明 && 是枚举成员声明(符号.值声明)) {
                    links.declaredType = checkExpression(符号.值声明.初始化!)
                }
            }
            返回 links.declaredType!
        }

        函数 获取程序声明的类型(符号: 符号_) {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                links.declaredType = 创建对象类型(对象标志_.程序_, 符号)
            }
            返回 links.declaredType!
        }

        函数 getSymbolAtLocation(node: 节点_): 符号_ | 未定 {
            假如 (node.种类) {
                若是 语法_.标识符_:
                若是 语法_.属性访问表达式_:
                若是 语法_.限定名_:
                    返回 getSymbolOfEntityNameOrPropertyAccessExpression(<限定名_ | 属性访问表达式_>node);
                若是 语法_.函数_:
                若是 语法_.等右尖号_:
                    返回 getSymbolOfNode(node.父节点);

                默认:
                    返回 未定;
            }
        }


        函数 getSymbolOfEntityNameOrPropertyAccessExpression(entityName: 实体名称_ | 属性访问表达式_): 符号_ | 未定 {
            如果 (是声明名称(entityName)) {
                返回 getSymbolOfNode(entityName.父节点);
            }

            如果 (是限定名称或属性访问的右侧(entityName)) {
                entityName = <限定名_ | 属性访问实体名称表达式_>entityName.父节点;
            }

            如果 (是表达式节点(entityName)) {
                如果 (节点是失踪(entityName)) {
                    // Missing entity name.
                    返回 未定;
                }

                如果 (entityName.种类 === 语法_.标识符_) {
                    返回 resolveEntityName(entityName, 符号标志_.值_, /*ignoreErrors*/ 为假, /*dontResolveAlias*/ 为真);
                }
                否则 如果 (entityName.种类 === 语法_.属性访问表达式_ || entityName.种类 === 语法_.限定名_) {
                    常量 links = getNodeLinks(entityName);
                    如果 (links.解析的符号) {
                        返回 links.解析的符号;
                    }

                    如果 (entityName.种类 === 语法_.属性访问表达式_) {
                        checkPropertyAccessExpression(entityName);
                    }
                    否则 {
                        checkQualifiedName(entityName);
                    }
                    返回 links.解析的符号;
                }
            }
            否则 如果 (是类型引用标识符(<实体名称_>entityName)) {
                如果 (entityName.父节点.种类 === 语法_.类型引用_) {
                    返回 resolveEntityName(<实体名称_>entityName, 符号标志_.类型_, /*ignoreErrors*/ 为假, /*dontResolveAlias*/ 为真);
                }
            }

            返回 未定;
        }

        函数 是类型引用标识符(entityName: 实体名称_): 真假 {
            变量 node: 节点_ = entityName;
            判断 (node.父节点 && node.父节点.种类 === 语法_.限定名_) {
                node = node.父节点;
            }

            返回 node.父节点 && node.父节点.种类 === 语法_.类型引用_;
        }

        函数 检查元素访问表达式(node: 元素访问表达式_) {
            变量 表达式类型 = checkExpression(node.表达式);
            变量 参数类型 = checkExpression(node.参数表达式)
            如果 (是数组类型(表达式类型) || 是列表类型(表达式类型)) {
                参数类型 // 参数类型只能是 整数类的
                返回 表达式类型.基础类型
            }
            如果 (是词典类型(表达式类型)) {
                参数类型 // 参数类型只能是 表达式类型.键类型
                返回 表达式类型.值类型
            }
            如果 (是文本类型(表达式类型)) {
                返回 字符类型
            }
            // 错误
            返回 未知类型
        }

        函数 checkPropertyAccessExpression(node: 属性访问表达式_) {
            返回 checkPropertyAccessExpressionOrQualifiedName(node, node.表达式, node.名称);
        }

        函数 checkQualifiedName(node: 限定名_) {
            返回 checkPropertyAccessExpressionOrQualifiedName(node, node.左侧, node.右侧);
        }

        函数 checkPropertyAccessExpressionOrQualifiedName(node: 属性访问表达式_ | 限定名_, left: 表达式_ | 限定名_, right: 标识符_) {
            变量 leftType = checkExpression(left);
            常量 parentSymbol = getNodeLinks(left).解析的符号;
            如果 (是指针类型(leftType)) {
                leftType = (<指针类型_>leftType).基础类型
            }
            常量 prop = getPropertyOfType(leftType, right.文本);

            如果 (是标识符(left) && parentSymbol) {
                markAliasReferenced(parentSymbol, node);
            }
            返回 getTypeOfSymbol(prop!)
        }

        函数 isNonLocalAlias(符号: 符号_, excludes = 符号标志_.值_ | 符号标志_.类型_) {
            返回 符号 && (符号.标志 & (符号标志_.别名_ | excludes)) === 符号标志_.别名_;
        }

        函数 markAliasReferenced(符号: 符号_, location: 节点_) {
            location
            如果 (isNonLocalAlias(符号, /*excludes*/ 符号标志_.值_)) {
                markAliasSymbolAsReferenced(符号);
            }
        }

        函数 markAliasSymbolAsReferenced(符号: 符号_) {
            常量 links = getSymbolLinks(符号);
            如果 (!links.referenced) {
                links.referenced = 为真;
                常量 node = getDeclarationOfAliasSymbol(符号);
                调试_.断言(!!node);
            }
        }

        函数 getSymbolOfNode(node: 节点_): 符号_ {
            返回 getMergedSymbol(node.符号!);
        }

        函数 getResolvedSymbol(node: 标识符_): 符号_ {
            常量 links = getNodeLinks(node);
            如果 (!links.解析的符号) {
                links.解析的符号 = !节点是失踪(node) &&
                    解析名称(
                        node,
                        node.文本,
                        符号标志_.值_,
                        诊断信息_.Cannot_find_name_0,
                        node,
                        !isWriteOnlyAccess(node),
                        为假,
                        诊断信息_.Cannot_find_name_0_Did_you_mean_1) || 未知符号;
            }
            返回 links.解析的符号;
        }

        函数 checkIdentifier(node: 标识符_): 类型_ {
            常量 符号 = getResolvedSymbol(node);
            如果 (符号 === 未知符号) {
                返回 通用类型;
            }
            如果 (符号.标志 & 符号标志_.别名_) {
                常量 别名符号 = resolveAlias(符号)
                返回 getTypeOfSymbol(别名符号)
            }
            返回 getTypeOfSymbol(符号);
        }

        函数 checkBinaryExpression(node: 二元表达式_, checkMode?: 检查模式_) {
            返回 checkBinaryLikeExpression(node.左侧, node.运算符令牌, node.右侧, checkMode, node);
        }

        函数 checkNonNullType(
            类型: 类型_,
            node: 节点_,
            undefinedDiagnostic?: 诊断信息_,
        ): 类型_ {
            常量 种类 = 类型.标志 & 类型标志_.未定_;
            如果 (种类) {
                error(node, (undefinedDiagnostic || 诊断信息_.Object_is_possibly_undefined));
                返回 未知类型
            }
            返回 类型;
        }


        函数 checkBinaryLikeExpression(left: 表达式_, operatorToken: 节点_, right: 表达式_, checkMode?: 检查模式_, errorNode?: 节点_) {
            常量 operator = operatorToken.种类;
            变量 leftType = checkExpression(left, checkMode);
            变量 rightType = checkExpression(right, checkMode);
            假如 (operator) {
                若是 语法_.星号_:
                若是 语法_.星等号_:
                若是 语法_.斜杠号_:
                若是 语法_.斜杠等号_:
                若是 语法_.百分号_:
                若是 语法_.百分等号_:
                若是 语法_.减号_:
                若是 语法_.减等号_:
                若是 语法_.双左尖号_:
                若是 语法_.双左尖等号_:
                若是 语法_.双右尖号_:
                若是 语法_.双右尖等号_:
                若是 语法_.或号_:
                若是 语法_.或等号_:
                若是 语法_.且号_:
                若是 语法_.且等号_:
                若是 语法_.异或号_:
                若是 语法_.异或等号_:

                    leftType = checkNonNullType(leftType, left);
                    rightType = checkNonNullType(rightType, right);

                    // 如果 a user tries to apply a bitwise operator to 2 boolean operands
                    // try and 返回 them a helpful suggestion
                    如果 ((leftType.标志 & 类型标志_.真假类型_) && (rightType.标志 & 类型标志_.真假类型_) && getSuggestedBooleanOperator(operatorToken.种类) !== 未定) {
                        error(errorNode || operatorToken, 诊断信息_.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, `tokenToString(operatorToken.种类)`, `tokenToString(suggestedOperator)`);
                    }
                    否则 {
                        // otherwise just check each operand separately and report errors as normal
                        常量 leftOk = checkArithmeticOperandType(left, leftType, 诊断信息_.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                        常量 rightOk = checkArithmeticOperandType(right, rightType, 诊断信息_.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type);
                        如果 (leftOk && rightOk) {
                            checkAssignmentOperator(整数类型);
                        }
                    }

                    返回 整数类型;
                若是 语法_.加号_:
                若是 语法_.加等号_:
                    如果 (!isTypeAssignableToKind(leftType, 类型标志_.文本类型_) && !isTypeAssignableToKind(rightType, 类型标志_.文本类型_)) {
                        leftType = checkNonNullType(leftType, left);
                        rightType = checkNonNullType(rightType, right);
                    }

                    变量 resultType: 类型_;
                    如果 (isTypeAssignableToKind(leftType, 类型标志_.数字类型_, /*strict*/ 为真) && isTypeAssignableToKind(rightType, 类型标志_.数字类型_, /*strict*/ 为真)) {
                        // Operands of an enum 类型 are treated as having the primitive 类型 Number.
                        // If both operands are of the Number primitive 类型, the result is of the Number primitive 类型.
                        resultType = 整数类型;
                    }
                    否则 如果 (isTypeAssignableToKind(leftType, 类型标志_.文本类型_, /*strict*/ 为真) || isTypeAssignableToKind(rightType, 类型标志_.文本类型_, /*strict*/ 为真)) {
                        // If one or both operands are of the String primitive 类型, the result is of the String primitive 类型.
                        resultType = 文本类型;
                    }

                    如果 (!resultType!) {
                        reportOperatorError();
                        返回 未知类型;
                    }

                    如果 (operator === 语法_.加等号_) {
                        checkAssignmentOperator(resultType!);
                    }
                    返回 resultType!;
                若是 语法_.左尖号_:
                若是 语法_.右尖号_:
                若是 语法_.左尖等号_:
                若是 语法_.右尖等号_:
                    返回 真假类型;
                若是 语法_.双等号_:
                若是 语法_.叹号等号_:
                    如果 (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
                        reportOperatorError();
                    }
                    返回 真假类型;
                若是 语法_.双或号_:
                    返回 getTypeFacts(leftType) & TypeFacts.Falsy ? getUnionType([rightType], UnionReduction.Subtype) : leftType;
                若是 语法_.等号_:
                    checkAssignmentOperator(rightType);
                    返回 getRegularTypeOfObjectLiteral(rightType);
            }

            函数 getSuggestedBooleanOperator(operator: 语法_): 语法_ | 未定 {
                假如 (operator) {
                    若是 语法_.或号_:
                    若是 语法_.或等号_:
                        返回 语法_.双或号_;
                    若是 语法_.异或号_:
                    若是 语法_.异或等号_:
                        返回 语法_.叹号等号_;
                    若是 语法_.且号_:
                    若是 语法_.且等号_:
                        返回 语法_.双且号_;
                    默认:
                        返回 未定;
                }
            }

            函数 checkAssignmentOperator(valueType: 类型_): 无值 {
                如果 (生产诊断 && 是赋值运算符(operator)) {
                    // TypeScript 1.0 spec (April 2014): 4.17
                    // An assignment of the form
                    //    VarExpr = ValueExpr
                    // requires VarExpr to be classified as a reference
                    // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1)
                    // and the 类型 of the non - compound operation to be assignable to the 类型 of VarExpr.
                    如果 (checkReferenceExpression(left, 诊断信息_.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)) {
                        // to avoid cascading errors check assignability only 如果 'isReference' check succeeded and no errors were reported
                        checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ 未定);
                    }
                }
            }

            函数 reportOperatorError() {
                error(errorNode || operatorToken, 诊断信息_.Operator_0_cannot_be_applied_to_types_1_and_2, `tokenToString(operatorToken.种类)`, `typeToString(leftType)`, `typeToString(rightType)`);
            }
        }

        函数 checkReferenceExpression(expr: 表达式_, invalidReferenceMessage: 诊断信息_): 真假_ {
            // References are combinations of identifiers, parentheses, and property accesses.
            常量 node = skipOuterExpressions(expr, 外部表达式种类_.Parentheses);
            如果 (node.种类 !== 语法_.标识符_ && node.种类 !== 语法_.括号表达式_) {
                error(expr, invalidReferenceMessage);
                返回 为假;
            }
            返回 为真;
        }


        函数 checkArithmeticOperandType(operand: 节点_, 类型: 类型_, diagnostic: 诊断信息_): 真假 {
            如果 (!isTypeAssignableToKind(类型, 类型标志_.数字类型_)) {
                error(operand, diagnostic);
                返回 为假;
            }
            返回 为真;
        }

        函数 createInferenceContext(typeParameters: 类型参数_[], signature: 签名_ | 未定, 标志: InferenceFlags, compareTypes?: 类型比较器_, baseInferences?: 推断信息_[]): 推断上下文_ {
            常量 inferences = baseInferences ? baseInferences.映射(cloneInferenceInfo) : typeParameters.映射(createInferenceInfo);
            常量 context = 映射 转为 推断上下文_;
            context.类型参数 = typeParameters;
            context.签名 = signature!;
            context.inferences = inferences;
            context.标志 = 标志;
            context.compareTypes = compareTypes || compareTypesAssignable;
            返回 context;

            函数 映射(t: 类型_): 类型_ {
                循环 (变量 i = 0; i < inferences.长度; i++) {
                    如果 (t === inferences[i].类型参数) {
                        inferences[i].isFixed = 为真;
                        返回 getInferredType(context, i);
                    }
                }
                返回 t;
            }
        }

        函数 isObjectLiteralType(类型: 类型_) {
            返回 !!(getObjectFlags(类型) & 对象标志_.字面量_);
        }

        函数 getWidenedType(类型: 类型_) {
            返回 getWidenedTypeWithContext(类型, /*context*/ 未定!);
        }

        函数 createWideningContext(parent: WideningContext, propertyName: 文字, siblings: 类型_[]): WideningContext {
            返回 { 父节点: parent, 属性名: propertyName, siblings, resolvedPropertyNames: 未定 };
        }

        函数 getWidenedTypeWithContext(类型: 类型_, context: WideningContext): 类型_ {
            如果 (类型.标志 & (类型标志_.未定_ | 类型标志_.联合_)) {
                如果 (类型.标志 & 类型标志_.未定_) {
                    返回 通用类型;
                }
                如果 (isObjectLiteralType(类型)) {
                    返回 getWidenedTypeOfObjectLiteral(类型, context);
                }
                如果 (类型.标志 & 类型标志_.联合_) {
                    常量 unionContext = context || createWideningContext(/*parent*/ 未定!, /*propertyName*/ 未定!, (<联合类型_>类型).类型组);
                    常量 widenedTypes = sameMap((<联合类型_>类型).类型组, t => t.标志 & 类型标志_.未定_ ? t : getWidenedTypeWithContext(t, unionContext));
                    // Widening an empty object literal transitions from a highly restrictive 类型 to
                    // a highly inclusive one. For that reason we perform subtype reduction here 如果 the
                    // union includes empty object types (e.g. reducing {} | string to just {}).
                    返回 getUnionType(widenedTypes, 某些(widenedTypes, isEmptyObjectType) ? UnionReduction.Subtype : UnionReduction.Literal);
                }
            }
            返回 类型;
        }

        函数 widenObjectLiteralCandidates(candidates: 类型_[]): 类型_[] {
            如果 (candidates.长度 > 1) {
                常量 objectLiterals = 过滤器(candidates, isObjectLiteralType);
                如果 (objectLiterals.长度) {
                    常量 objectLiteralsType = getWidenedType(getUnionType(objectLiterals, UnionReduction.Subtype));
                    返回 组合(过滤器(candidates, t => !isObjectLiteralType(t)), [objectLiteralsType]);
                }
            }
            返回 candidates;
        }

        函数 getWidenedTypeOfObjectLiteral(类型: 类型_, context: WideningContext): 类型_ {
            常量 members = 创建符号表();
            循环 (常量 prop 属于 getPropertiesOfObjectType(类型)) {
                // Since get accessors already widen their 返回 value there is no need to
                // widen accessor based properties here.
                members.设置(prop.名称, prop.标志 & 符号标志_.属性_ ? getWidenedProperty(prop, context) : prop);
            }
            如果 (context) {
                循环 (常量 name 属于 getPropertyNamesOfContext(context)) {
                    如果 (!members.具有(name)) {
                        members.设置(name, getUndefinedProperty(name));
                    }
                }
            }
            返回 createAnonymousType(类型.符号!, members, 空符号表);
        }

        函数 getUndefinedProperty(name: 文字) {
            常量 cached = undefinedProperties.获取(name);
            如果 (cached) {
                返回 cached;
            }
            常量 result = createSymbol(符号标志_.属性_, name);
            result.类型 = 未定类型;
            undefinedProperties.设置(name, result);
            返回 result;
        }

        函数 getWidenedProperty(prop: 符号_, context: WideningContext): 符号_ {
            常量 original = getTypeOfSymbol(prop);
            常量 propContext = context && createWideningContext(context, prop.名称, /*siblings*/ 未定!);
            常量 widened = getWidenedTypeWithContext(original, propContext);
            返回 widened === original ? prop : createSymbolWithType(prop, widened);
        }

        函数 createSymbolWithType(source: 符号_, 类型: 类型_) {
            常量 符号 = createSymbol(source.标志, source.名称);
            符号.声明组 = source.声明组;
            符号.父符号 = source.父符号;
            符号.类型 = 类型;
            符号.目标 = source;
            如果 (source.值声明) {
                符号.值声明 = source.值声明;
            }
            返回 符号;
        }

        函数 getPropertyNamesOfContext(context: WideningContext): 文字[] {
            如果 (!context.resolvedPropertyNames) {
                常量 names = 创建词典<真假>();
                循环 (常量 t 属于 getSiblingsOfContext(context)) {
                    如果 (isObjectLiteralType(t)) {
                        循环 (常量 prop 属于 getPropertiesOfType(t)) {
                            names.设置(prop.名称, 为真);
                        }
                    }
                }
                context.resolvedPropertyNames = 数组从(names.键组());
            }
            返回 context.resolvedPropertyNames;
        }

        函数 getSiblingsOfContext(context: WideningContext): 类型_[] {
            如果 (!context.siblings) {
                常量 siblings: 类型_[] = [];
                循环 (常量 类型 属于 getSiblingsOfContext(context.父节点!)) {
                    如果 (isObjectLiteralType(类型)) {
                        常量 prop = getPropertyOfObjectType(类型, context.属性名!);
                        如果 (prop) {
                            forEachType(getTypeOfSymbol(prop), t => {
                                siblings.压入(t);
                            });
                        }
                    }
                }
                context.siblings = siblings;
            }
            返回 context.siblings;
        }

        函数 forEachType<T>(类型: 类型_, f: (t: 类型_) => T): T | 未定 {
            返回 类型.标志 & 类型标志_.联合_ ? 循环执行((<联合类型_>类型).类型组, f) : f(类型);
        }

        函数 getInferredType(context: 推断上下文_, index: 数字): 类型_ {
            常量 inference = context.inferences[index];
            变量 inferredType = inference.inferredType;
            如果 (!inferredType) {
                常量 signature = context.签名;
                如果 (signature) {
                    如果 (inference.candidates) {
                        // Extract all object literal types and replace them with a single widened and normalized 类型.
                        常量 candidates = widenObjectLiteralCandidates(inference.candidates);
                        // We widen inferred literal types 如果
                        // all inferences were made to top-level ocurrences of the 类型 parameter, and
                        // the 类型 parameter has no constraint or its constraint includes no primitive or literal types, and
                        // the 类型 parameter was fixed during inference or does not occur at top-level in the 返回 类型.
                        常量 widenLiteralTypes = inference.topLevel &&
                            !hasPrimitiveConstraint(inference.类型参数) &&
                            (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.类型参数));
                        常量 baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
                        // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, 如果
                        // union types were requested or 如果 all inferences were made from the 返回 类型 position, infer a
                        // union 类型. Otherwise, infer a common supertype.
                        常量 unwidenedType = context.标志 & InferenceFlags.InferUnionTypes || inference.priority & InferencePriority.PriorityImpliesUnion ?
                            getUnionType(baseCandidates, UnionReduction.Subtype) :
                            getCommonSupertype(baseCandidates);
                        inferredType = getWidenedType(unwidenedType);
                    }
                    否则 如果 (inference.contraCandidates) {
                        // We only have contravariant inferences, infer the best common subtype of those
                        inferredType = getCommonSubtype(inference.contraCandidates);
                    }
                    否则 {
                        // Infer either the default or the empty object 类型 when no inferences were
                        // made. It is important to remember that in this case, inference still
                        // succeeds, meaning there is no error for not having inference candidates. An
                        // inference error only occurs when there are *conflicting* candidates, i.e.
                        // candidates with no common supertype.
                        常量 defaultType = getDefaultFromTypeParameter(inference.类型参数);
                        如果 (defaultType) {
                            // Instantiate the default 类型. Any forward reference to a 类型
                            // parameter should be instantiated to the empty object 类型.
                            inferredType = instantiateType(defaultType,
                                combineTypeMappers(
                                    createBackreferenceMapper(context.签名.typeParameters!, index),
                                    context));
                        }
                        否则 {
                            inferredType = getDefaultTypeArgumentType();
                        }
                    }
                }
                否则 {
                    inferredType = getTypeFromInference(inference);
                }

                inferredType = getWidenedUniqueESSymbolType(inferredType);
                inference.inferredType = inferredType;

                常量 constraint = getConstraintOfTypeParameter(inference.类型参数);
                如果 (constraint) {
                    常量 instantiatedConstraint = instantiateType(constraint, context);
                    如果 (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) {
                        inference.inferredType = inferredType = getWidenedUniqueESSymbolType(instantiatedConstraint);
                    }
                }
            }

            返回 inferredType;
        }

        函数 getWidenedLiteralType(类型: 类型_): 类型_ {
            返回 类型
        }

        函数 hasPrimitiveConstraint(类型: 类型参数_): 真假 {
            常量 constraint = getConstraintOfTypeParameter(类型);
            返回 !!(constraint && maybeTypeOfKind(constraint, 类型标志_.文本类型_));
        }

        函数 getCommonSubtype(types: 类型_[]) {
            返回 reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s);
        }

        函数 getCommonSupertype(types: 类型_[]): 类型_ {
            返回 getUnionType(types, UnionReduction.Subtype);
        }

        函数 getTypeFromInference(inference: 推断信息_) {
            返回 inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
                inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
                    通用类型
        }

        函数 createBackreferenceMapper(typeParameters: 类型参数_[], index: 数字): 类型映射_ {
            返回 t => typeParameters.索引位于(t) >= index ? 通用类型 : t;
        }

        函数 getDefaultTypeArgumentType(): 类型_ {
            返回 通用类型;
        }

        函数 getWidenedUniqueESSymbolType(类型: 类型_): 类型_ {
            返回 类型
        }

        函数 createInferenceInfo(typeParameter: 类型参数_): 推断信息_ {
            返回 {
                类型参数: typeParameter,
                candidates: 未定!,
                contraCandidates: 未定!,
                inferredType: 未定!,
                priority: 未定!,
                topLevel: 为真,
                isFixed: 为假
            };
        }

        函数 cloneInferenceInfo(inference: 推断信息_): 推断信息_ {
            返回 {
                类型参数: inference.类型参数,
                candidates: inference.candidates && inference.candidates.分切(),
                contraCandidates: inference.contraCandidates && inference.contraCandidates.分切(),
                inferredType: inference.inferredType,
                priority: inference.priority,
                topLevel: inference.topLevel,
                isFixed: inference.isFixed
            };
        }

        函数 forEachMatchingParameterType(source: 签名_, 目标: 签名_, callback: (s: 类型_, t: 类型_) => 无值) {
            常量 sourceMax = source.参数.长度;
            常量 targetMax = 目标.参数.长度;
            变量 count: 数字;
            如果 (source.具有剩余参数 && 目标.具有剩余参数) {
                count = 数学_.max(sourceMax, targetMax);
            }
            否则 如果 (source.具有剩余参数) {
                count = targetMax;
            }
            否则 如果 (目标.具有剩余参数) {
                count = sourceMax;
            }
            否则 {
                count = 数学_.min(sourceMax, targetMax);
            }
            循环 (变量 i = 0; i < count; i++) {
                callback(getTypeAtPosition(source, i), getTypeAtPosition(目标, i));
            }
        }

        函数 isTypeParameterAtTopLevel(类型: 类型_, typeParameter: 类型参数_): 真假 {
            返回 !!(类型 === typeParameter || 类型.标志 & (类型标志_.联合_ | 类型标志_.交叉_) && 循环执行((<联合或交叉类型_>类型).类型组, t => isTypeParameterAtTopLevel(t, typeParameter)));
        }

        函数 couldContainTypeVariables(类型: 类型_): 真假 {
            常量 objectFlags = getObjectFlags(类型);
            返回 !!(类型.标志 & 类型标志_.类型参数_ ||
                objectFlags & 对象标志_.引用_ && 循环执行((<类型引用_>类型).类型实参, couldContainTypeVariables) ||
                objectFlags & 对象标志_.匿名_ && 类型.符号 && 类型.符号.标志 & (符号标志_.函数_ | 符号标志_.方法_ | 符号标志_.类型字面量_) ||
                类型.标志 & (类型标志_.联合_ | 类型标志_.交叉_) && couldUnionOrIntersectionContainTypeVariables(<联合或交叉类型_>类型));
        }

        函数 couldUnionOrIntersectionContainTypeVariables(类型: 联合或交叉类型_): 真假 {
            如果 (类型.couldContainTypeVariables === 未定) {
                类型.couldContainTypeVariables = 循环执行(类型.类型组, couldContainTypeVariables)!;
            }
            返回 类型.couldContainTypeVariables;
        }

        函数 typeIdenticalToSomeType(类型: 类型_, types: 类型_[]): 真假 {
            循环 (常量 t 属于 types) {
                如果 (isTypeIdenticalTo(t, 类型)) {
                    返回 为真;
                }
            }
            返回 为假;
        }

        函数 removeTypesFromUnionOrIntersection(类型: 联合或交叉类型_, typesToRemove: 类型_[]) {
            常量 reducedTypes: 类型_[] = [];
            循环 (常量 t 属于 类型.类型组) {
                如果 (!typeIdenticalToSomeType(t, typesToRemove)) {
                    reducedTypes.压入(t);
                }
            }
            返回 类型.标志 & 类型标志_.联合_ ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes);
        }

        函数 createTypeEraser(sources: 类型参数_[]): 类型映射_ {
            返回 createTypeMapper(sources, /*targets*/ 未定!);
        }

        函数 getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(类型: 类型_): 类型_ | 未定 {
            如果 (类型.标志 & (类型标志_.类型参数_ | 类型标志_.联合_ | 类型标志_.交叉_)) {
                常量 constraint = getResolvedBaseConstraint(<可实例化类型_ | 联合或交叉类型_>类型);
                返回 constraint !== 无约束类型 && constraint !== 循环自身约束类型 ? constraint : 未定;
            }
            返回 未定
        }

        函数 getBaseConstraintOfType(类型: 类型_): 类型_ | 未定 {
            返回 getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(类型);
        }

        函数 cloneTypeParameter(typeParameter: 类型参数_): 类型参数_ {
            常量 result = <类型参数_>创建类型(类型标志_.类型参数_);
            result.符号 = typeParameter.符号;
            result.目标 = typeParameter;
            返回 result;
        }

        函数 instantiateSignature(signature: 签名_, 映射: 类型映射_, eraseTypeParameters?: 真假): 签名_ {
            变量 freshTypeParameters: 类型参数_[];
            如果 (signature.typeParameters && !eraseTypeParameters) {
                // First create a fresh set of 类型 parameters, then include a mapping from the old to the
                // new 类型 parameters in the 映射 function. Finally store this 映射 in the new 类型
                // parameters such that we can use it when instantiating constraints.
                freshTypeParameters = 词典(signature.typeParameters, cloneTypeParameter);
                映射 = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), 映射);
                循环 (常量 tp 属于 freshTypeParameters) {
                    tp.映射 = 映射;
                }
            }
            // Don't compute resolvedReturnType and resolvedTypePredicate now,
            // because using `映射` now could trigger inferences to become fixed. (See `createInferenceContext`.)
            // See GH#17600.
            常量 result = createSignature(signature.declaration, freshTypeParameters!,
                instantiateList(signature.参数!, 映射, instantiateSymbol) 转为 [],
                /*resolvedReturnType*/ 未定,
                signature.minArgumentCount,
                signature.具有剩余参数!);
            result.目标 = signature;
            result.映射 = 映射;
            返回 result;
        }

        函数 getBaseSignature(signature: 签名_) {
            常量 typeParameters = signature.typeParameters;
            如果 (typeParameters) {
                常量 typeEraser = createTypeEraser(typeParameters);
                常量 baseConstraints = 词典(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp)!, typeEraser) || 通用类型);
                返回 instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ 为真);
            }
            返回 signature;
        }

        函数 getMarkerTypeReference(类型: 泛型类型_, source: 类型参数_, 目标: 类型_) {
            常量 result = createTypeReference(类型, 词典(类型.类型参数, t => t === source ? 目标 : t));
            result.对象标志 |= 对象标志_.标记类型_;
            返回 result;
        }

        函数 getVariances(类型: 泛型类型_): Variance[] {
            常量 typeParameters = 类型.类型参数 || 空数组;
            变量 variances = 类型.variances;
            如果 (!variances) {
                类型.variances = 空数组;
                variances = [];
                循环 (常量 tp 属于 typeParameters) {
                    常量 typeWithSuper = getMarkerTypeReference(类型, tp, markerSuperType);
                    常量 typeWithSub = getMarkerTypeReference(类型, tp, markerSubType);
                    变量 variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? Variance.Covariant : 0) |
                        (isTypeAssignableTo(typeWithSuper, typeWithSub) ? Variance.Contravariant : 0);
                    // If the instantiations appear to be related bivariantly it may be because the
                    // 类型 parameter is independent (i.e. it isn't witnessed anywhere in the generic
                    // 类型). To determine this we compare instantiations where the 类型 parameter is
                    // replaced with marker types that are known to be unrelated.
                    如果 (variance === Variance.Bivariant && isTypeAssignableTo(getMarkerTypeReference(类型, tp, markerOtherType), typeWithSuper)) {
                        variance = Variance.Independent;
                    }
                    variances.压入(variance);
                }
                类型.variances = variances;
            }
            返回 variances;
        }

        函数 inferTypes(inferences: 推断信息_[], originalSource: 类型_, originalTarget: 类型_, priority: InferencePriority = 0) {
            变量 symbolStack: 符号_[];
            变量 visited: 词典_<真假>;
            变量 contravariant = 为假;
            变量 propagationType: 类型_;
            inferFromTypes(originalSource, originalTarget);

            函数 inferFromTypes(source: 类型_, 目标: 类型_) {
                如果 (!couldContainTypeVariables(目标)) {
                    返回;
                }
                如果 (source.标志 & 类型标志_.通用_) {
                    // We are inferring from an 'any' 类型. We want to infer this 类型 for every 类型 parameter
                    // referenced in the 目标 类型, so we record it as the propagation 类型 and infer from the
                    // 目标 to itself. Then, as we find candidates we substitute the propagation 类型.
                    常量 savePropagationType = propagationType;
                    propagationType = source;
                    inferFromTypes(目标, 目标);
                    propagationType = savePropagationType;
                    返回;
                }
                如果 (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === 目标.aliasSymbol) {
                    // Source and 目标 are types originating in the same generic 类型 alias declaration.
                    // Simply infer from source 类型 arguments to 目标 类型 arguments.
                    常量 sourceTypes = source.aliasTypeArguments!;
                    常量 targetTypes = 目标.aliasTypeArguments!;
                    循环 (变量 i = 0; i < sourceTypes.长度; i++) {
                        inferFromTypes(sourceTypes[i], targetTypes[i]);
                    }
                    返回;
                }
                如果 (source.标志 & 类型标志_.联合_ && 目标.标志 & 类型标志_.联合_ ||
                    source.标志 & 类型标志_.交叉_ && 目标.标志 & 类型标志_.交叉_) {
                    // Source and 目标 are both unions or both intersections. If source and 目标
                    // are the same 类型, just relate each constituent 类型 to itself.
                    如果 (source === 目标) {
                        循环 (常量 t 属于 (<联合或交叉类型_>source).类型组) {
                            inferFromTypes(t, t);
                        }
                        返回;
                    }
                    // Find each source constituent 类型 that has an identically matching 目标 constituent
                    // 类型, and for each such 类型 infer from the 类型 to itself. When inferring from a
                    // 类型 to itself we effectively find all 类型 parameter occurrences within that 类型
                    // and infer themselves as their 类型 arguments. We have special handling for numeric
                    // and string literals because the number and string types are not represented as unions
                    // of all their possible values.
                    变量 matchingTypes!: 类型_[];
                    循环 (常量 t 属于 (<联合或交叉类型_>source).类型组) {
                        如果 (typeIdenticalToSomeType(t, (<联合或交叉类型_>目标).类型组)) {
                            (matchingTypes || (matchingTypes = [])).压入(t);
                            inferFromTypes(t, t);
                        }
                    }
                    // Next, to improve the quality of inferences, reduce the source and 目标 types by
                    // removing the identically matched constituents. For example, when inferring from
                    // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'.
                    如果 (matchingTypes) {
                        source = removeTypesFromUnionOrIntersection(<联合或交叉类型_>source, matchingTypes);
                        目标 = removeTypesFromUnionOrIntersection(<联合或交叉类型_>目标, matchingTypes);
                    }
                }
                如果 (目标.标志 & 类型标志_.类型参数_) {
                    // If 目标 is a 类型 parameter, make an inference, unless the source 类型 contains
                    // the anyFunctionType (the wildcard 类型 that's used to avoid contextually typing functions).
                    // Because the anyFunctionType is internal, it should not be exposed to the user by adding
                    // it as an inference candidate. Hopefully, a better candidate will come along that does
                    // not contain anyFunctionType when we come back to this argument for its second round
                    // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard
                    // when constructing types from 类型 parameters that had no inference candidates).
                    如果 (source === 未知类型) {
                        返回;
                    }
                    常量 inference = getInferenceInfoForType(目标);
                    如果 (inference) {
                        如果 (!inference.isFixed) {
                            如果 (inference.priority === 未定 || priority < inference.priority) {
                                inference.candidates = 未定!;
                                inference.contraCandidates = 未定!;
                                inference.priority = priority;
                            }
                            如果 (priority === inference.priority) {
                                常量 candidate = propagationType || source;
                                如果 (contravariant) {
                                    inference.contraCandidates = 追加(inference.contraCandidates, candidate)!;
                                }
                                否则 {
                                    inference.candidates = 追加(inference.candidates, candidate)!;
                                }
                            }
                            如果 (!(priority & InferencePriority.ReturnType) && 目标.标志 & 类型标志_.类型参数_ && !isTypeParameterAtTopLevel(originalTarget, <类型参数_>目标)) {
                                inference.topLevel = 为假;
                            }
                        }
                        返回;
                    }
                }
                如果 (getObjectFlags(source) & 对象标志_.引用_ && getObjectFlags(目标) & 对象标志_.引用_ && (<类型引用_>source).目标 === (<类型引用_>目标).目标) {
                    // If source and 目标 are references to the same generic 类型, infer from 类型 arguments
                    常量 sourceTypes = (<类型引用_>source).类型实参 || 空数组;
                    常量 targetTypes = (<类型引用_>目标).类型实参 || 空数组;
                    常量 count = sourceTypes.长度 < targetTypes.长度 ? sourceTypes.长度 : targetTypes.长度;
                    常量 variances = getVariances((<类型引用_>source).目标);
                    循环 (变量 i = 0; i < count; i++) {
                        如果 (i < variances.长度 && variances[i] === Variance.Contravariant) {
                            inferFromContravariantTypes(sourceTypes[i], targetTypes[i]);
                        }
                        否则 {
                            inferFromTypes(sourceTypes[i], targetTypes[i]);
                        }
                    }
                }
                否则 如果 (目标.标志 & (类型标志_.联合_ | 类型标志_.交叉_)) {
                    常量 targetTypes = (<联合或交叉类型_>目标).类型组;
                    变量 typeVariableCount = 0;
                    变量 typeVariable: 类型参数_
                    // First infer to each 类型 in union or intersection that isn't a 类型 variable
                    循环 (常量 t 属于 targetTypes) {
                        如果 (getInferenceInfoForType(t)) {
                            typeVariable = <类型参数_>t;
                            typeVariableCount++;
                        }
                        否则 {
                            inferFromTypes(source, t);
                        }
                    }
                    // Next, 如果 目标 containings a single naked 类型 variable, make a secondary inference to that 类型
                    // variable. This gives meaningful results for union types in co-variant positions and intersection
                    // types in contra-variant positions (such as callback parameters).
                    如果 (typeVariableCount === 1) {
                        常量 savePriority = priority;
                        priority |= InferencePriority.NakedTypeVariable;
                        inferFromTypes(source, typeVariable!);
                        priority = savePriority;
                    }
                }
                否则 如果 (source.标志 & 类型标志_.联合_) {
                    // Source is a union or intersection 类型, infer from each constituent 类型
                    常量 sourceTypes = (<联合或交叉类型_>source).类型组;
                    循环 (常量 sourceType 属于 sourceTypes) {
                        inferFromTypes(sourceType, 目标);
                    }
                }
                否则 {
                    如果 (!(priority & InferencePriority.NoConstraints && source.标志 & (类型标志_.交叉_ | 类型标志_.类型参数_))) {
                        source = getApparentType(source);
                    }
                    如果 (source.标志 & (类型标志_.对象_ | 类型标志_.交叉_)) {
                        常量 key = source.id + "," + 目标.id;
                        如果 (visited && visited.获取(key)) {
                            返回;
                        }
                        (visited || (visited = 创建词典<真假>())).设置(key, 为真);
                        常量 符号 = 未定;
                        如果 (符号) {
                            如果 (包含(symbolStack, 符号)) {
                                返回;
                            }
                            (symbolStack || (symbolStack = [])).压入(符号);
                            inferFromObjectTypes(source, 目标);
                            symbolStack.弹出();
                        }
                        否则 {
                            inferFromObjectTypes(source, 目标);
                        }
                    }
                }
            }

            函数 inferFromContravariantTypes(source: 类型_, 目标: 类型_) {
                如果 (priority & InferencePriority.AlwaysStrict) {
                    contravariant = !contravariant;
                    inferFromTypes(source, 目标);
                    contravariant = !contravariant;
                }
                否则 {
                    inferFromTypes(source, 目标);
                }
            }

            函数 getInferenceInfoForType(类型: 类型_) {
                如果 (类型.标志 & 类型标志_.类型参数_) {
                    循环 (常量 inference 属于 inferences) {
                        如果 (类型 === inference.类型参数) {
                            返回 inference;
                        }
                    }
                }
                返回 未定;
            }

            函数 inferFromObjectTypes(source: 类型_, 目标: 类型_) {
                // Infer from the members of source and 目标 only 如果 the two types are possibly related. We check
                // in both directions because we may be inferring for a co-variant or a contra-variant position.
                如果 (!getUnmatchedProperty(source, 目标) || !getUnmatchedProperty(目标, source)) {
                    inferFromProperties(source, 目标);
                    inferFromSignatures(source, 目标);
                }
            }

            函数 inferFromProperties(source: 类型_, 目标: 类型_) {
                常量 properties = getPropertiesOfObjectType(目标);
                循环 (常量 targetProp 属于 properties) {
                    常量 sourceProp = getPropertyOfType(source, targetProp.名称);
                    如果 (sourceProp) {
                        inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp));
                    }
                }
            }

            函数 inferFromSignatures(source: 类型_, 目标: 类型_) {
                常量 sourceSignatures = getSignaturesOfType(source);
                常量 targetSignatures = getSignaturesOfType(目标);
                常量 sourceLen = sourceSignatures.长度;
                常量 targetLen = targetSignatures.长度;
                常量 len = sourceLen < targetLen ? sourceLen : targetLen;
                循环 (变量 i = 0; i < len; i++) {
                    inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i]));
                }
            }

            函数 inferFromSignature(source: 签名_, 目标: 签名_) {
                forEachMatchingParameterType(source, 目标, inferFromContravariantTypes);
                inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(目标));
            }

        }

        函数 instantiateSignatureInContextOf(signature: 签名_, contextualSignature: 签名_, contextualMapper?: 类型映射_, compareTypes?: 类型比较器_): 签名_ {
            常量 context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.InferUnionTypes, compareTypes);
            forEachMatchingParameterType(contextualSignature, signature, (source, 目标) => {
                // 类型_ parameters from outer context referenced by source 类型 are fixed by instantiation of the source 类型
                inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), 目标);
            });
            如果 (!contextualMapper) {
                inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), InferencePriority.ReturnType);
            }
            返回 getSignatureInstantiation(signature, getInferredTypes(context));
        }

        函数 getInferredTypes(context: 推断上下文_): 类型_[] {
            常量 result: 类型_[] = [];
            循环 (变量 i = 0; i < context.inferences.长度; i++) {
                result.压入(getInferredType(context, i));
            }
            返回 result;
        }

        函数 getSignatureInstantiation(signature: 签名_, typeArguments: 类型_[]): 签名_ {
            typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters));
            常量 instantiations = signature.instantiations || (signature.instantiations = 创建词典<签名_>());
            常量 id = getTypeListId(typeArguments);
            变量 instantiation = instantiations.获取(id);
            如果 (!instantiation) {
                instantiations.设置(id, instantiation = createSignatureInstantiation(signature, typeArguments));
            }
            返回 instantiation;
        }

        函数 createSignatureInstantiation(signature: 签名_, typeArguments: 类型_[]): 签名_ {
            返回 instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ 为真);
        }

        函数 createSignatureTypeMapper(signature: 签名_, typeArguments: 类型_[]): 类型映射_ {
            返回 createTypeMapper(signature.typeParameters!, typeArguments);
        }

        函数 instantiateTypeWithSingleGenericCallSignature(n: 表达式_ | 方法声明_, 类型: 类型_, 检查模式?: 检查模式_) {
            如果 (检查模式 === 检查模式_.推理的_) {
                常量 signature = getSingleCallSignature(类型);
                如果 (signature && signature.typeParameters) {
                    常量 contextualType = getApparentTypeOfContextualType(<表达式_>n);
                    如果 (contextualType) {
                        常量 contextualSignature = getSingleCallSignature(contextualType);
                        如果 (contextualSignature && !contextualSignature.typeParameters) {
                            返回 getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(n)));
                        }
                    }
                }
            }
            返回 类型;
        }

        函数 checkExpressionForMutableLocation(node: 表达式_, checkMode: 检查模式_, contextualType?: 类型_): 类型_ {
            contextualType
            如果 (arguments.长度 === 2) {
                contextualType = getContextualType(node);
            }
            常量 类型 = checkExpression(node, checkMode);
            返回 类型;
        }

        函数 checkPropertyAssignment(node: 结构字面量成员表达式_, checkMode?: 检查模式_): 类型_ {
            返回 checkExpressionForMutableLocation(node.初始化, checkMode!);
        }

        // Return the contextual 类型 for a given expression node. During overload resolution, a contextual 类型 may temporarily
        // be "pushed" onto a node using the contextualType property.
        函数 getApparentTypeOfContextualType(node: 表达式_): 类型_ | 未定 {
            变量 contextualType = getContextualType(node);
            contextualType = contextualType && mapType(contextualType, getApparentType);
            如果 (!(contextualType && contextualType.标志 & 类型标志_.联合_ && isObjectLiteralExpression(node))) {
                返回 contextualType;
            }
            // Keep the below up-to-date with the work done within `isRelatedTo` by `findMatchingDiscriminantType`
            变量 match: 类型_ | 未定;
            propLoop: 循环 (常量 prop 属于 node.属性组) {
                如果 (!prop.符号) 继续;
                如果 (prop.种类 !== 语法_.结构字面量成员表达式_) 继续;
                如果 (isDiscriminantProperty(contextualType, prop.符号.名称)) {
                    常量 discriminatingType = getTypeOfNode(prop.初始化)!;
                    循环 (常量 类型 属于 (contextualType 转为 联合类型_).类型组) {
                        常量 targetType = getTypeOfPropertyOfType(类型, prop.符号.名称);
                        如果 (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ 未定!)) {
                            如果 (match) {
                                如果 (类型 === match) 继续; // Finding multiple fields which discriminate to the same 类型 is fine
                                match = 未定;
                                跳出 propLoop;
                            }
                            match = 类型;
                        }
                    }
                }
            }
            返回 match || contextualType;
        }

        函数 mapType(类型: 类型_, 映射: (t: 类型_) => 类型_, noReductions?: 真假): 类型_ {
            如果 (!(类型.标志 & 类型标志_.联合_)) {
                返回 映射(类型);
            }
            常量 types = (<联合类型_>类型).类型组;
            变量 mappedType: 类型_;
            变量 mappedTypes: 类型_[];
            循环 (常量 current 属于 types) {
                常量 t = 映射(current);
                如果 (t) {
                    如果 (!mappedType!) {
                        mappedType = t;
                    }
                    否则 如果 (!mappedTypes!) {
                        mappedTypes = [mappedType, t];
                    }
                    否则 {
                        mappedTypes!.压入(t);
                    }
                }
            }
            返回 mappedTypes! ? getUnionType(mappedTypes, noReductions ? UnionReduction.无_ : UnionReduction.Literal) : mappedType;
        }

        函数 getTypeOfPropertyOfContextualType(类型: 类型_, name: 文字) {
            返回 mapType(类型, t => {
                常量 prop = t.标志 & 类型标志_.结构化类型_ ? getPropertyOfType(t, name) : 未定!;
                返回 prop ? getTypeOfSymbol(prop) : 未定!;
            }, /*noReductions*/ 为真);
        }
        
        函数 getContextualTypeForObjectLiteralElement(element: 结构字面量成员表达式_) {
            常量 objectLiteral = <结构字面量成员表达式_>element.父节点;
            常量 类型 = getApparentTypeOfContextualType(objectLiteral);
            如果 (类型) {
                常量 symbolName = getSymbolOfNode(element).名称
                常量 propertyType = getTypeOfPropertyOfContextualType(类型, symbolName);
                如果 (propertyType) {
                    返回 propertyType;
                }
            }

            返回 未定;
        }

        函数 getContextualType(node: 表达式_): 类型_ | 未定 {
            如果 (node.上下文类型_) {
                返回 node.上下文类型_;
            }
            常量 parent = node.父节点;
            假如 (parent.种类) {
                若是 语法_.变量声明_:
                    返回 getContextualTypeForInitializerExpression(node);
                若是 语法_.箭头函数_:
                若是 语法_.返回语句_:
                    返回 getContextualTypeForReturnExpression(node);
                若是 语法_.调用表达式_:
                    返回 getContextualTypeForArgument(<调用表达式_>parent, node);
                若是 语法_.类型转换表达式_:
                    返回 getTypeFromTypeNode((<类型转换表达式_>parent).类型);
                若是 语法_.二元表达式_:
                    返回 getContextualTypeForBinaryOperand(node);
                若是 语法_.结构字面量成员表达式_:
                    // TODO
                    返回 getContextualTypeForObjectLiteralElement(<结构字面量成员表达式_>parent);
                若是 语法_.数组字面量表达式_: {
                    常量 arrayLiteral = <数组字面量表达式_>parent;
                    常量 类型 = getApparentTypeOfContextualType(arrayLiteral);
                    // TODO
                    返回 类型
                }
                若是 语法_.条件表达式_:
                    返回 getContextualTypeForConditionalOperand(node);
                若是 语法_.模板跨度_:
                    调试_.断言(parent.父节点.种类 === 语法_.模板表达式_);
                    返回 getContextualTypeForSubstitutionExpression(<模板表达式_>parent.父节点, node);
                若是 语法_.括号表达式_: {
                    返回 getContextualType(<括号表达式_>parent);
                }
            }
            返回 未定;
        }

        函数 getContextualTypeForConditionalOperand(node: 表达式_): 类型_ | 未定 {
            常量 conditional = <条件表达式_>node.父节点;
            返回 node === conditional.当为真 || node === conditional.当为假 ? getContextualType(conditional) : 未定;
        }

        函数 getContextualTypeForSubstitutionExpression(template: 模板表达式_, substitutionExpression: 表达式_) {
            如果 (template.父节点.种类 === 语法_.标记模板表达式_) {
                返回 getContextualTypeForArgument(<标记模板表达式_>template.父节点, substitutionExpression);
            }
            返回 未定;
        }

        函数 getContextualTypeForBinaryOperand(node: 表达式_): 类型_ | 未定 {
            常量 binaryExpression = <二元表达式_>node.父节点;
            常量 { 左侧, 运算符令牌, 右侧 } = binaryExpression;
            假如 (运算符令牌.种类) {
                若是 语法_.等号_:
                    返回 未定;
                若是 语法_.双或号_:
                    常量 类型 = getContextualType(binaryExpression);
                    返回 !类型 && node === 右侧 ? getTypeOfExpression(左侧, /*cache*/ 为真) : 类型;
                若是 语法_.双且号_:
                若是 语法_.逗号_:
                    返回 node === 右侧 ? getContextualType(binaryExpression) : 未定;
                默认:
                    返回 未定;
            }
        }

        函数 getContextualTypeForArgument(callTarget: 调用族表达式_, arg: 表达式_): 类型_ | 未定 {
            常量 args = getEffectiveCallArguments(callTarget);
            常量 argIndex = args.索引位于(arg);
            返回 argIndex === -1 ? 未定 : getContextualTypeForArgumentAtIndex(callTarget, argIndex);
        }

        函数 getContextualTypeForArgumentAtIndex(callTarget: 调用族表达式_, argIndex: 数字): 类型_ | 未定 {
            常量 signature = getNodeLinks(callTarget).resolvedSignature === 解析中签名 ? 解析中签名 : getResolvedSignature(callTarget);
            返回 getTypeAtPosition(signature, argIndex);
        }

        函数 getContextualTypeForInitializerExpression(node: 表达式_): 类型_ | 未定 {
            变量 父节点 = node.父节点
            假如 (父节点.种类) {
                若是 语法_.变量语句_:
                若是 语法_.简洁变量语句_: {
                    变量 祖父 = <变量语句_ | 简洁变量语句_>node.父节点
                    变量 索引 = 祖父.初始化组!.索引位于(node)
                    如果 (索引 !== -1) {
                        变量 变量声明 = 祖父.声明组[索引]
                        如果 (变量声明 && 变量声明.类型) {
                            返回 getTypeFromTypeNode(变量声明.类型)
                        }
                    }
                }
            }
            返回 未定;
        }

        函数 getContextualTypeForReturnExpression(node: 表达式_): 类型_ | 未定 {
            常量 func = getContainingFunction(node);
            如果 (func) {
                返回 getContextualReturnType(func);
            }
            返回 未定;
        }

        函数 getContextualReturnType(functionDecl: 签名声明_): 类型_ | 未定 {
            常量 signature = getContextualSignatureForFunctionLikeDeclaration(<函数表达式_>functionDecl);
            如果 (signature && !isResolvingReturnTypeOfSignature(signature)) {
                返回 getReturnTypeOfSignature(signature);
            }
            返回 未定;
        }

        函数 isResolvingReturnTypeOfSignature(signature: 签名_) {
            返回 !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 类型系统属性名称_.解析的返回类型_) >= 0;
        }

        函数 getContextualSignatureForFunctionLikeDeclaration(node: 函数族声明_): 签名_ | 未定 {
            // Only function expressions, arrow functions, and object literal methods are contextually typed.
            返回 isFunctionExpressionOrArrowFunction(node) ? getContextualSignature(<函数表达式_>node) : 未定;
        }

        函数 getContextualSignature(node: 函数表达式_ | 箭头函数_ | 方法声明_): 签名_ | 未定 {
            调试_.断言(node.种类 !== 语法_.方法声明_);
            常量 类型 = getApparentTypeOfContextualType(<表达式_>node);
            如果 (!类型) {
                返回 未定;
            }
            如果 (!(类型.标志 & 类型标志_.联合_)) {
                返回 getContextualCallSignature(类型, node);
            }
            变量 signatureList!: 签名_[];
            常量 types = (<联合类型_>类型).类型组
            循环 (常量 current 属于 types) {
                常量 signature = getContextualCallSignature(current, node);
                如果 (signature) {
                    如果 (!signatureList) {
                        // This signature will contribute to contextual union signature
                        signatureList = [signature];
                    }
                    否则 如果 (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ 为假, /*ignoreThisTypes*/ 为真, /*ignoreReturnTypes*/ 为真, compareTypesIdentical)) {
                        // Signatures aren't identical, do not use
                        返回 未定;
                    }
                    否则 {
                        // Use this signature for contextual union signature
                        signatureList.压入(signature);
                    }
                }
            }

            // Result is union of signatures collected (返回 类型 is union of 返回 types of this signature set)
            变量 result!: 签名_;
            如果 (signatureList) {
                result = cloneSignature(signatureList[0]);
                result.unionSignatures = signatureList;
            }
            返回 result;
        }

        函数 isFunctionExpressionOrArrowFunction(n: 节点_): n 作为 函数表达式_ | 箭头函数_ {
            返回 n.种类 === 语法_.函数表达式_ || n.种类 === 语法_.箭头函数_;
        }

        函数 getContextualCallSignature(类型: 类型_, node: 函数表达式_ | 箭头函数_ | 方法声明_): 签名_ | 未定 {
            常量 signatures = getSignaturesOfType(类型);
            如果 (signatures.长度 === 1) {
                常量 signature = signatures[0];
                如果 (!isAritySmaller(signature, node)) {
                    返回 signature;
                }
            }
            返回 未定;
        }

        /** If the contextual signature has fewer parameters than the function expression, do not use it */
        函数 isAritySmaller(signature: 签名_, 目标: 函数表达式_ | 箭头函数_ | 方法声明_) {
            变量 targetParameterCount = 0;
            如果 (!目标.参数) {
                返回 未定
            }
            循环 (; targetParameterCount < 目标.参数!.长度; targetParameterCount++) {
                常量 param = 目标.参数![targetParameterCount];
                如果 (param.类型 && 是剩余参数(param)) {
                    跳出;
                }
            }
            常量 sourceLength = signature.具有剩余参数 ? 数字_.__最大_有效值__ : signature.参数.长度;
            返回 sourceLength < targetParameterCount;
        }



        函数 isTypeDeclarationName(name: 节点_): 真假 {
            返回 name.种类 === 语法_.标识符_ &&
                isTypeDeclaration(name.父节点) &&
                (<名称声明_>name.父节点).名称 === name;
        }

        函数 isTypeDeclaration(node: 节点_): 真假 {
            假如 (node.种类) {
                若是 语法_.类型参数声明_:
                若是 语法_.结构声明_:
                若是 语法_.接口声明_:
                若是 语法_.类型别名声明_:
                若是 语法_.类型声明_:
                若是 语法_.枚举声明_:
                    返回 为真;
            }
            返回 为假;
        }

        函数 getTypeOfNode(node: 节点_): 类型_ | 未定 {
            如果 (是类型节点的一部分(node)) {
                返回 getTypeFromTypeNode(<类型节点_>node);;
            }
            如果 (是表达式节点(node)) {
                返回 getRegularTypeOfExpression(<表达式_>node);
            }
            如果 (isTypeDeclaration(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                常量 符号 = getSymbolOfNode(node);
                返回 getDeclaredTypeOfSymbol(符号);
            }
            如果 (isTypeDeclarationName(node)) {
                常量 符号 = getSymbolAtLocation(node);
                返回 符号 && getDeclaredTypeOfSymbol(符号);
            }
            如果 (是声明(node)) {
                // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration
                常量 符号 = getSymbolOfNode(node);
                返回 getTypeOfSymbol(符号);
            }
            如果 (是声明名称(node)) {
                常量 符号 = getSymbolAtLocation(node);
                返回 符号 && getTypeOfSymbol(符号);
            }
            返回 未知类型
        }

        函数 getRegularTypeOfExpression(expr: 表达式_): 类型_ {
            如果 (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
                expr = <表达式_>expr.父节点;
            }
            返回 getRegularTypeOfLiteralType(getTypeOfExpression(expr));
        }

        函数 getTypeOfExpression(node: 表达式_, cache?: 真假) {
            // Optimize for the common case of a call to a function with a single non-generic call
            // signature where we can just fetch the 返回 类型 without checking the arguments.
            如果 (node.种类 === 语法_.调用表达式_) {
                常量 funcType = checkExpression((<调用表达式_>node).表达式);
                常量 signature = getSingleCallSignature(funcType);
                如果 (signature && !signature.typeParameters) {
                    返回 getReturnTypeOfSignature(signature);
                }
            }
            // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
            // should have a parameter that indicates whether full error checking is required such that
            // we can perform the optimizations locally.
            返回 cache ? checkExpressionCached(node) : checkExpression(node);
        }

        函数 getUnionOrIntersectionProperty(类型: 联合或交叉类型_, name: 文字): 符号_ | 未定 {
            常量 properties = 类型.propertyCache || (类型.propertyCache = 创建符号表());
            变量 property = properties.获取(name);
            如果 (!property) {
                property = createUnionOrIntersectionProperty(类型, name);
                如果 (property) {
                    properties.设置(name, property);
                }
            }
            返回 property;
        }

        函数 createUnionOrIntersectionProperty(containingType: 联合或交叉类型_, name: 文字): 符号_ | 未定 {
            变量 props: 符号_[];
            常量 isUnion = containingType.标志 & 类型标志_.联合_;
            变量 syntheticFlag = CheckFlags.SyntheticMethod;
            变量 checkFlags = 0;
            循环 (常量 current 属于 containingType.类型组) {
                常量 类型 = getApparentType(current);
                如果 (类型 !== 未知类型) {
                    常量 prop = getPropertyOfType(类型, name);
                    如果 (prop) {
                        props = 附加如果唯一(props!, prop);
                        如果 (!isMethodLike(prop)) {
                            syntheticFlag = CheckFlags.SyntheticProperty;
                        }
                    }
                    否则 如果 (isUnion) {
                        checkFlags |= CheckFlags.Partial;
                    }
                }
            }
            如果 (!props) {
                返回 未定;
            }
            如果 (props.长度 === 1 && !(checkFlags & CheckFlags.Partial)) {
                返回 props[0];
            }
            常量 propTypes: 类型_[] = [];
            常量 declarations: 声明_[] = [];
            变量 commonType: 类型_;
            循环 (常量 prop 属于 props) {
                如果 (prop.声明组) {
                    添加范围(declarations, prop.声明组);
                }
                常量 类型 = getTypeOfSymbol(prop);
                如果 (!commonType!) {
                    commonType = 类型;
                }
                否则 如果 (类型 !== commonType) {
                    checkFlags |= CheckFlags.HasNonUniformType;
                }
                propTypes.压入(类型);
            }
            常量 result = createSymbol(符号标志_.属性_, name, syntheticFlag | checkFlags);
            result.containingType = containingType;
            result.声明组 = declarations;
            result.类型 = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes);
            返回 result;
        }

        函数 isMethodLike(符号: 符号_) {
            返回 !!(符号.标志 & 符号标志_.方法_ || getCheckFlags(符号) & CheckFlags.SyntheticMethod);
        }

        函数 isDiscriminantProperty(类型: 类型_, name: 文字) {
            如果 (类型 && 类型.标志 & 类型标志_.联合_) {
                常量 prop = getUnionOrIntersectionProperty(<联合类型_>类型, name);
                如果 (prop && getCheckFlags(prop) & CheckFlags.SyntheticProperty) {
                    如果 ((<临时符号_>prop).isDiscriminantProperty === 未定) {
                        (<临时符号_>prop).isDiscriminantProperty = !!((<临时符号_>prop).checkFlags & CheckFlags.HasNonUniformType);
                    }
                    返回 (<临时符号_>prop).isDiscriminantProperty;
                }
            }
            返回 为假;
        }

        函数 getContextualMapper(node: 节点_) {
            node = 查找祖先(node, n => !!n.contextualMapper)!;
            返回 node ? node.contextualMapper : identityMapper;
        }

        函数 getOrCreateTypeFromSignature(signature: 签名_): 对象类型_ {
            // There are two ways to declare a construct signature, one is by declaring a class constructor
            // using the constructor keyword, and the other is declaring a bare construct signature in an
            // object 类型 literal or interface (using the new keyword). Each way of declaring a constructor
            // will result in a different declaration 种类.
            如果 (!signature.isolatedSignatureType) {
                常量 类型 = <解析类型_>创建对象类型(对象标志_.匿名_);
                类型.成员 = 空符号表;
                类型.属性组 = 空数组;
                signature.isolatedSignatureType = 类型;
            }

            返回 signature.isolatedSignatureType;
        }

        函数 checkExpressionCached(node: 表达式_, checkMode?: 检查模式_): 类型_ {
            常量 links = getNodeLinks(node);
            如果 (!links.resolvedType) {
                如果 (checkMode) {
                    返回 checkExpression(node, checkMode);
                }
                // When computing a 类型 that we're going to cache, we need to ignore any ongoing control flow
                // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart
                // to the top of the stack ensures all transient types are computed from a known point.
                常量 saveFlowLoopStart = flowLoopStart;
                flowLoopStart = flowLoopCount;
                links.resolvedType = checkExpression(node, checkMode);
                flowLoopStart = saveFlowLoopStart;
            }
            返回 links.resolvedType;
        }

        函数 checkExpression(n: 表达式_ | 限定名_, 检查模式?: 检查模式_): 类型_ {
            变量 类型: 类型_;
            如果 (n.种类 === 语法_.限定名_) {
                类型 = checkQualifiedName(<限定名_>n);
            }
            否则 {
                常量 未实例化类型 = checkExpressionWorker(n, 检查模式!);
                类型 = instantiateTypeWithSingleGenericCallSignature(n, 未实例化类型, 检查模式);
            }
            返回 类型;
        }

        函数 createSignature(
            declaration: 签名声明_,
            typeParameters: 类型参数_[],
            parameters: 符号_[],
            resolvedReturnType: 类型_ | 未定,
            minArgumentCount: 数字,
            hasRestParameter: 真假,
        ): 签名_ {
            常量 sig = 新建 签名_(检查);
            sig.declaration = declaration;
            sig.typeParameters = typeParameters;
            sig.参数 = parameters;
            sig.resolvedReturnType = resolvedReturnType;
            sig.minArgumentCount = minArgumentCount;
            sig.具有剩余参数 = hasRestParameter;
            返回 sig;
        }

        函数 cloneSignature(sig: 签名_): 签名_ {
            返回 createSignature(sig.declaration, sig.typeParameters!, sig.参数, 未定, sig.minArgumentCount, sig.具有剩余参数);
        }

        函数 resolveUntypedCall(node: 调用族表达式_): 签名_ {
            如果 (node.种类 === 语法_.标记模板表达式_) {
                checkExpression(node.模板);
            }
            返回 解析中签名;
        }

        函数 resolveErrorCall(node: 调用族表达式_): 签名_ {
            resolveUntypedCall(node);
            返回 解析中签名;
        }

        函数 getEffectiveCallArguments(node: 调用族表达式_): 只读数组_<表达式_> {
            如果 (node.种类 === 语法_.标记模板表达式_) {
                常量 template = node.模板;
                常量 args: 表达式_[] = [未定!];
                如果 (template.种类 === 语法_.模板表达式_) {
                    循环执行(template.模板跨度组, span => {
                        args.压入(span.表达式);
                    });
                }
                返回 args;
            }
            否则 如果 (node.种类 === 语法_.创建表达式_) {
                常量 args: 表达式_[] = [];
                如果 ((<创建表达式_>node).实参1) args.压入((<创建表达式_>node).实参1!)
                如果 ((<创建表达式_>node).实参2) args.压入((<创建表达式_>node).实参2!)
                返回 args
            }
            否则 {
                返回 (<任意>node).实参组 || 空数组;
            }
        }

        函数 isContextSensitive(node: 表达式_ | 方法声明_ | 结构字面量表达式_): 真假 {
            调试_.断言(node.种类 !== 语法_.方法声明_);
            假如 (node.种类) {
                若是 语法_.函数表达式_:
                若是 语法_.箭头函数_:
                若是 语法_.方法声明_:
                    返回 isContextSensitiveFunctionLikeDeclaration(<函数表达式_ | 箭头函数_ | 方法声明_>node);
                若是 语法_.结构字面量表达式_:
                    返回 !!循环执行((<结构字面量表达式_>node).属性组, isContextSensitive);
                若是 语法_.数组字面量表达式_:
                    返回 !!循环执行((<数组字面量表达式_>node).元素, isContextSensitive);
                若是 语法_.条件表达式_:
                    返回 isContextSensitive((<条件表达式_>node).当为真) || isContextSensitive((<条件表达式_>node).当为假);
                若是 语法_.二元表达式_:
                    返回 (<二元表达式_>node).运算符令牌.种类 === 语法_.双或号_ && (isContextSensitive((<二元表达式_>node).左侧) || isContextSensitive((<二元表达式_>node).右侧));
                若是 语法_.结构字面量成员表达式_:
                    返回 isContextSensitive((<结构字面量成员表达式_>node).初始化);
                若是 语法_.括号表达式_:
                    返回 isContextSensitive((<括号表达式_>node).表达式);
            }

            返回 为假;
        }

        函数 isContextSensitiveFunctionLikeDeclaration(node: 普通数族声明_) {
            // Functions with 类型 parameters are not context sensitive.
            如果 (node.类型参数) {
                返回 为假;
            }
            // Functions with any parameters that lack 类型 annotations are context sensitive.
            如果 (循环执行(node.参数, p => !getEffectiveTypeAnnotationNode(p))) {
                返回 为真;
            }
            // TODO(anhans): A block should be context-sensitive 如果 it has a context-sensitive 返回 value.
            返回 node.主体!.种类 === 语法_.块_ ? 为假 : isContextSensitive(<表达式_>node.主体);
        }

        函数 reorderCandidates(signatures: 签名_[], result: 签名_[]): 无值 {
            变量 lastParent: 节点_;
            变量 lastSymbol: 符号_;
            变量 cutoffIndex = 0;
            变量 index: 数字;
            变量 spliceIndex: 数字;
            调试_.断言(!result.长度);
            循环 (常量 signature 属于 signatures) {
                常量 符号 = signature.declaration && signature.declaration.符号;
                常量 parent = signature.declaration && signature.declaration.父节点;
                如果 (!lastSymbol! || 符号 === lastSymbol) {
                    如果 (lastParent! && parent === lastParent) {
                        index!++;
                    }
                    否则 {
                        lastParent = parent;
                        index = cutoffIndex;
                    }
                }
                否则 {
                    // current declaration belongs to a different 符号
                    // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex
                    index = cutoffIndex = result.长度;
                    lastParent = parent;
                }
                lastSymbol = 符号;

                spliceIndex = index!;

                result.分离(spliceIndex, 0, signature);
            }
        }

        函数 getEffectiveArgumentType(node: 调用族表达式_, argIndex: 数字): 类型_ {
            // Decorators provide special arguments, a tagged template expression provides
            // a special first argument, and string literals get string literal types
            // unless we're reporting errors
            如果 (argIndex === 0 && node.种类 === 语法_.标记模板表达式_) {
                返回 文本类型;
            }

            返回 未定!;
        }

        函数 inferTypeArguments(node: 调用族表达式_, signature: 签名_, args: 只读数组_<表达式_>, excludeArgument: 真假[], context: 推断上下文_): 类型_[] {
            // Clear out all the inference results from the last time inferTypeArguments was called on this context
            循环 (常量 inference 属于 context.inferences) {
                // As an optimization, we don't have to clear (and later recompute) inferred types
                // for 类型 parameters that have already been fixed on the previous call to inferTypeArguments.
                // It would be just as correct to reset all of them. But then we'd be repeating the same work
                // for the 类型 parameters that were fixed, namely the work done by getInferredType.
                如果 (!inference.isFixed) {
                    inference.inferredType = 未定!;
                }
            }

            // We perform two passes over the arguments. In the first pass we infer from all arguments, but use
            // wildcards for all context sensitive function expressions.
            常量 argCount = args.长度;
            循环 (变量 i = 0; i < argCount; i++) {
                常量 arg = getEffectiveArgument(node, args, i);
                // If the effective argument is '未定', then it is an argument that is present but is synthetic.
                如果 (arg === 未定 || arg.种类 !== 语法_.省略表达式_) {
                    常量 paramType = getTypeAtPosition(signature, i);
                    变量 argType = getEffectiveArgumentType(node, i);

                    // If the effective argument 类型 is '未定', there is no synthetic 类型
                    // for the argument. In that case, we should check the argument.
                    如果 (argType === 未定) {
                        // For context sensitive arguments we pass the identityMapper, which is a signal to treat all
                        // context sensitive function expressions as wildcards
                        常量 映射 = excludeArgument && excludeArgument[i] !== 未定 ? identityMapper : context;
                        argType = checkExpressionWithContextualType(arg!, paramType, 映射);
                    }

                    inferTypes(context.inferences, argType, paramType);
                }
            }

            // In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this
            // time treating function expressions normally (which may cause previously inferred 类型 arguments to be fixed
            // as we construct types for contextually typed parameters)
            // Decorators will not have `excludeArgument`, as their arguments cannot be contextually typed.
            // Tagged template expressions will always have `未定` for `excludeArgument[0]`.
            如果 (excludeArgument) {
                循环 (变量 i = 0; i < argCount; i++) {
                    // No need to check for omitted args and template expressions, their exclusion value is always 未定
                    如果 (excludeArgument[i] === 为假) {
                        常量 arg = args[i];
                        常量 paramType = getTypeAtPosition(signature, i);
                        inferTypes(context.inferences, checkExpressionWithContextualType(arg, paramType, context), paramType);
                    }
                }
            }
            返回 getInferredTypes(context);
        }

        函数 checkTypeArguments(signature: 签名_, typeArgumentNodes: 只读数组_<类型节点_>, reportErrors: 真假, headMessage?: 诊断信息_): 类型_[] | 为假 {
            常量 typeParameters = signature.typeParameters!;
            常量 typeArgumentTypes = fillMissingTypeArguments(词典(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters));
            变量 映射!: 类型映射_;
            循环 (变量 i = 0; i < typeArgumentNodes.长度; i++) {
                调试_.断言(typeParameters[i] !== 未定, "Should not call checkTypeArguments with too many 类型 arguments");
                常量 constraint = getConstraintOfTypeParameter(typeParameters[i]);
                如果 (!constraint) 继续;

                常量 errorInfo = reportErrors && headMessage ? (() => 诊断消息链(/*details*/ 未定!, 诊断信息_.Type_0_does_not_satisfy_the_constraint_1)) : 未定!;
                常量 typeArgumentHeadMessage = headMessage || 诊断信息_.Type_0_does_not_satisfy_the_constraint_1;
                如果 (!映射) {
                    映射 = createTypeMapper(typeParameters, typeArgumentTypes);
                }
                常量 typeArgument = typeArgumentTypes[i];
                如果 (!checkTypeAssignableTo(
                    typeArgument,
                    getTypeWithThisArgument(instantiateType(constraint, 映射), typeArgument),
                    reportErrors ? typeArgumentNodes[i] : 未定!,
                    typeArgumentHeadMessage,
                    errorInfo)) {
                    返回 为假;
                }
            }
            返回 typeArgumentTypes;
        }


        函数 callLikeExpressionMayHaveTypeArguments(node: 调用族表达式_): node 作为 调用表达式_ {
            返回 node.种类 === 语法_.调用表达式_
        }

        函数 getLongestCandidateIndex(candidates: 签名_[], argsCount: 数字): 数字 {
            变量 maxParamsIndex = -1;
            变量 maxParams = -1;

            循环 (变量 i = 0; i < candidates.长度; i++) {
                常量 candidate = candidates[i];
                如果 (candidate.具有剩余参数 || candidate.参数.长度 >= argsCount) {
                    返回 i;
                }
                如果 (candidate.参数.长度 > maxParams) {
                    maxParams = candidate.参数.长度;
                    maxParamsIndex = i;
                }
            }

            返回 maxParamsIndex;
        }

        函数 resolveCall(node: 调用族表达式_, signatures: 签名_[], candidatesOutArray: 签名_[], fallbackError?: 诊断信息_): 签名_ {
            常量 isTaggedTemplate = node.种类 === 语法_.标记模板表达式_;

            变量 typeArguments!: 节点数组_<类型节点_>;

            如果 (!isTaggedTemplate) {
                typeArguments = (<调用表达式_>node).类型实参!;
            }

            常量 candidates = candidatesOutArray || [];
            // reorderCandidates fills up the candidates array directly
            reorderCandidates(signatures, candidates);
            如果 (!candidates.长度) {
                diagnostics.添加(创建诊断从节点(node, 诊断信息_.Call_target_does_not_contain_any_signatures));
                返回 resolveErrorCall(node);
            }

            常量 args = getEffectiveCallArguments(node);

            // The following applies to any value of 'excludeArgument[i]':
            //    - true:      the argument at 'i' is susceptible to a one-time permanent contextual typing.
            //    - 未定: the argument at 'i' is *not* susceptible to permanent contextual typing.
            //    - false:     the argument at 'i' *was* and *has been* permanently contextually typed.
            //
            // The idea is that we will perform 类型 argument inference & assignability checking once
            // without using the susceptible parameters that are functions, and once more for each of those
            // parameters, contextually typing each as we go along.
            //
            // For a tagged template, then the first argument be '未定' 如果 necessary
            // because it represents a TemplateStringsArray.
            //
            // For a decorator, no arguments are susceptible to contextual typing due to the fact
            // decorators are applied to a declaration by the emitter, and not to an expression.
            常量 isSingleNonGenericCandidate = candidates.长度 === 1 && !candidates[0].typeParameters;
            变量 excludeArgument: 真假[];
            变量 excludeCount = 0;
            如果 (!isSingleNonGenericCandidate) {
                // We do not need to call `getEffectiveArgumentCount` here as it only
                // applies when calculating the number of arguments for a decorator.
                循环 (变量 i = isTaggedTemplate ? 1 : 0; i < args.长度; i++) {
                    如果 (isContextSensitive(args[i])) {
                        如果 (!excludeArgument!) {
                            excludeArgument = 新建 数组_(args.长度);
                        }
                        excludeArgument![i] = 为真;
                        excludeCount++;
                    }
                }
            }

            // The following variables are captured and modified by calls to chooseOverload.
            // If overload resolution or 类型 argument inference fails, we want to report the
            // best error possible. The best error is one which says that an argument was not
            // assignable to a parameter. This implies that everything else about the overload
            // was fine. So 如果 there is any overload that is only incorrect because of an
            // argument, we will report an error on that one.
            //
            //     function foo(s: string): void;
            //     function foo(n: number): void; // Report argument error on this overload
            //     function foo(): void;
            //     foo(true);
            //
            // If none of the overloads even made it that far, there are two possibilities.
            // There was a problem with 类型 arguments for some overload, in which case
            // report an error on that. Or none of the overloads even had correct arity,
            // in which case give an arity error.
            //
            //     function foo<T extends string>(x: T): void; // Report 类型 argument error
            //     function foo(): void;
            //     foo<number>(0);
            //
            变量 candidateForArgumentError!: 签名_;
            变量 candidateForTypeArgumentError!: 签名_;
            变量 result: 签名_;

            // If we are in signature help, a trailing comma indicates that we intend to provide another argument,
            // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
            常量 signatureHelpTrailingComma =
                candidatesOutArray && node.种类 === 语法_.调用表达式_ && node.实参组.有尾随逗号;

            // Section 4.12.1:
            // 如果 the candidate list contains one or more signatures for which the 类型 of each argument
            // expression is a subtype of each corresponding parameter 类型, the 返回 类型 of the first
            // of those signatures becomes the 返回 类型 of the function call.
            // Otherwise, the 返回 类型 of the first signature in the candidate list becomes the 返回
            // 类型 of the function call.
            //
            // Whether the call is an error is determined by assignability of the arguments. The subtype pass
            // is just important for choosing the best signature. So in the case where there is only one
            // signature, the subtype pass is useless. So skipping it is an optimization.
            如果 (candidates.长度 > 1) {
                result = chooseOverload(candidates, 子类型关系, signatureHelpTrailingComma)!;
            }
            如果 (!result!) {
                result = chooseOverload(candidates, 可赋值关系, signatureHelpTrailingComma)!;
            }
            如果 (result!) {
                返回 result!;
            }

            // No signatures were applicable. Now report errors based on the last applicable signature with
            // no arguments excluded from assignability checks.
            // If candidate is 未定, it means that no candidates had a suitable arity. In that case,
            // skip the checkApplicableSignature check.
            如果 (candidateForArgumentError!) {
                checkApplicableSignature(node, args, candidateForArgumentError, 可赋值关系, /*excludeArgument*/ 未定!, /*reportErrors*/ 为真);
            }
            否则 如果 (candidateForTypeArgumentError) {
                checkTypeArguments(candidateForTypeArgumentError, (node 转为 调用表达式_).类型实参!, /*reportErrors*/ 为真, fallbackError);
            }
            否则 如果 (typeArguments && every(signatures, sig => 长度(sig.typeParameters!) !== typeArguments.长度)) {
                变量 min = 数字_.__正_无穷大__;
                变量 max = 数字_.__负_无穷大__;
                循环 (常量 sig 属于 signatures) {
                    min = 数学_.min(min, getMinTypeArgumentCount(sig.typeParameters));
                    max = 数学_.max(max, 长度(sig.typeParameters!));
                }
                常量 paramCount = min < max ? min + "-" + max : min;
                diagnostics.添加(创建诊断从节点数组(获取节点的源文件(node), typeArguments, 诊断信息_.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.长度));
            }
            否则 如果 (args) {
                变量 min = 数字_.__正_无穷大__;
                变量 max = 数字_.__负_无穷大__;
                循环 (常量 sig 属于 signatures) {
                    min = 数学_.min(min, sig.minArgumentCount);
                    max = 数学_.max(max, sig.参数.长度);
                }
                常量 hasRestParameter = 某些(signatures, sig => sig.具有剩余参数);
                常量 hasSpreadArgument = getSpreadArgumentIndex(args) > -1;
                常量 paramCount = hasRestParameter ? min :
                    min < max ? min + "-" + max :
                        min;
                变量 argCount = args.长度;
                如果 (argCount <= max && hasSpreadArgument) {
                    argCount--;
                }
                常量 error = hasRestParameter && hasSpreadArgument ? 诊断信息_.Expected_at_least_0_arguments_but_got_1_or_more :
                    hasRestParameter ? 诊断信息_.Expected_at_least_0_arguments_but_got_1 :
                        hasSpreadArgument ? 诊断信息_.Expected_0_arguments_but_got_1_or_more :
                            诊断信息_.Expected_0_arguments_but_got_1;
                diagnostics.添加(创建诊断从节点(node, error, paramCount, argCount));
            }
            否则 如果 (fallbackError) {
                diagnostics.添加(创建诊断从节点(node, fallbackError));
            }

            // No signature was applicable. We have already reported the errors for the invalid signature.
            // If this is a 类型 resolution session, e.g. Language Service, try to get better information than anySignature.
            // Pick the longest signature. This way we can get a contextual 类型 for cases like:
            //     declare function f(a: { xa: number; xb: number; }, b: number);
            //     f({ |
            // Also, use explicitly-supplied 类型 arguments 如果 they are provided, so we can get a contextual signature in cases like:
            //     declare function f<T>(k: keyof T);
            //     f<Foo>("
            如果 (!生产诊断) {
                调试_.断言(candidates.长度 > 0); // Else would have exited above.
                常量 bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === 未定 ? args.长度 : apparentArgumentCount);
                常量 candidate = candidates[bestIndex];

                常量 { typeParameters } = candidate;
                如果 (typeParameters && callLikeExpressionMayHaveTypeArguments(node) && node.类型实参) {
                    常量 typeArguments: 类型_[] = []
                    词典(node.类型实参, tn => {
                        变量 t = getTypeOfNode(tn)
                        如果 (t) {
                            typeArguments.压入(t)
                        }
                    }) //node.类型实参.映射(getTypeOfNode);
                    判断 (typeArguments.长度 > typeParameters.长度) {
                        typeArguments.弹出();
                    }
                    判断 (typeArguments.长度 < typeParameters.长度) {
                        typeArguments.压入(getDefaultTypeArgumentType());
                    }

                    常量 instantiated = createSignatureInstantiation(candidate, typeArguments);
                    candidates[bestIndex] = instantiated;
                    返回 instantiated;
                }

                返回 candidate;
            }

            返回 resolveErrorCall(node);

            函数 chooseOverload(candidates: 签名_[], relation: 词典_<关系比较结果_>, signatureHelpTrailingComma = 为假) {
                candidateForArgumentError = 未定!;
                candidateForTypeArgumentError = 未定!;

                如果 (isSingleNonGenericCandidate) {
                    常量 candidate = candidates[0];
                    如果 (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
                        返回 未定;
                    }
                    如果 (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ 为假)) {
                        candidateForArgumentError = candidate;
                        返回 未定;
                    }
                    返回 candidate;
                }

                循环 (变量 candidateIndex = 0; candidateIndex < candidates.长度; candidateIndex++) {
                    常量 originalCandidate = candidates[candidateIndex];
                    如果 (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) {
                        继续;
                    }

                    变量 candidate: 签名_;
                    常量 inferenceContext = originalCandidate.typeParameters ?
                        createInferenceContext(originalCandidate.typeParameters, originalCandidate, InferenceFlags.无_) :
                        未定;

                    判断 (为真) {
                        candidate = originalCandidate;
                        如果 (candidate.typeParameters) {
                            变量 typeArgumentTypes: 类型_[];
                            如果 (typeArguments) {
                                常量 typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ 为假);
                                如果 (typeArgumentResult) {
                                    typeArgumentTypes = typeArgumentResult;
                                }
                                否则 {
                                    candidateForTypeArgumentError = originalCandidate;
                                    跳出;
                                }
                            }
                            否则 {
                                typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext!);
                            }
                            candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
                        }
                        如果 (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ 为假)) {
                            candidateForArgumentError = candidate;
                            跳出;
                        }
                        如果 (excludeCount === 0) {
                            candidates[candidateIndex] = candidate;
                            返回 candidate;
                        }
                        excludeCount--;
                        如果 (excludeCount > 0) {
                            excludeArgument[excludeArgument.索引位于(/*value*/ 为真)] = 为假;
                        }
                        否则 {
                            excludeArgument = 未定!;
                        }
                    }
                }

                返回 未定;
            }
        }

        函数 resolveCallExpression(node: 调用表达式_, candidatesOutArray: 签名_[]): 签名_ {
            常量 funcType = checkNonNullType(
                checkExpression(node.表达式),
                node,
                诊断信息_.Cannot_invoke_an_object_which_is_possibly_undefined,
            );

            如果 (funcType === 未知类型) {
                返回 解析中签名;
            }
            常量 apparentType = getApparentType(funcType);

            如果 (apparentType === 未知类型) {
                // Another error has already been reported
                返回 resolveErrorCall(node);
            }

            // Technically, this signatures list may be incomplete. We are taking the apparent 类型,
            // but we are not including call signatures that may have been added to the Object or
            // Function interface, since they have none by default. This is a bit of a leap of faith
            // that the user will not add any.
            常量 callSignatures = getSignaturesOfType(apparentType);

            // TS 1.0 Spec: 4.12
            // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
            // types are provided for the argument expressions, and the result is always of 类型 Any.
            如果 (funcType.标志 & 类型标志_.类型参数_) {
                // The unknownType indicates that an error already occurred (and was reported).  No
                // need to report another error in this case.
                如果 (funcType !== 未知类型 && node.类型实参) {
                    error(node, 诊断信息_.Untyped_function_calls_may_not_accept_type_arguments);
                }
                返回 resolveUntypedCall(node);
            }
            // If FuncExpr's apparent 类型(section 3.8.1) is a function 类型, the call is a typed function call.
            // TypeScript employs overload resolution in typed function calls in order to support functions
            // with multiple call signatures.
            如果 (!callSignatures.长度) {
                invocationError(node);
                返回 resolveErrorCall(node);
            }
            返回 resolveCall(node, callSignatures, candidatesOutArray);
        }

        函数 invocationError(node: 节点_) {
            error(node, 诊断信息_.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, `typeToString(apparentType)`);
        }


        函数 hasCorrectArity(node: 调用族表达式_, args: 只读数组_<表达式_>, signature: 签名_, signatureHelpTrailingComma = 为假) {
            变量 argCount: 数字;            // Apparent number of arguments we will have in this call         
            变量 callIsIncomplete: 真假;           // In incomplete call we want to be lenient when we have too few arguments
            变量 spreadArgIndex = -1;

            如果 (node.种类 === 语法_.标记模板表达式_) {
                // Even 如果 the call is incomplete, we'll have a missing expression as our last argument,
                // so we can say the count is just the arg list length
                argCount = args.长度;

                如果 (node.模板.种类 === 语法_.模板表达式_) {
                    // If a tagged template expression lacks a tail literal, the call is incomplete.
                    // Specifically, a template only can end in a TemplateTail or a Missing literal.
                    常量 lastSpan = 最后或未定义(node.模板.模板跨度组);
                    调试_.断言(lastSpan !== 未定); // we should always have at least one span.
                    callIsIncomplete = 节点是失踪(lastSpan!.字面量) || !!lastSpan!.字面量.是未终止的;
                }
                否则 {
                    // If the template didn't end in a backtick, or its beginning occurred right prior to EOF,
                    // then this might actually turn out to be a TemplateHead in the future;
                    // so we consider the call to be incomplete.
                    常量 templateLiteral = <字面量表达式_>node.模板;
                    调试_.断言(templateLiteral.种类 === 语法_.无替换模板字面量_);
                    callIsIncomplete = !!templateLiteral.是未终止的;
                }
            }
            否则 {
                如果 (!(<任意>node).实参组) {
                    返回 signature.minArgumentCount === 0;
                }

                argCount = signatureHelpTrailingComma ? args.长度 + 1 : args.长度;

                // If we are missing the close parenthesis, the call is incomplete.
                callIsIncomplete = (<任意>node).实参组.尾位 === node.尾位;
                spreadArgIndex = getSpreadArgumentIndex(args);
            }

            // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range.
            如果 (spreadArgIndex >= 0) {
                返回 isRestParameterIndex(signature, spreadArgIndex) ||
                    signature.minArgumentCount <= spreadArgIndex && spreadArgIndex < signature.参数.长度;
            }

            // Too many arguments implies incorrect arity.
            如果 (!signature.具有剩余参数 && argCount > signature.参数.长度) {
                返回 为假;
            }

            // If the call is incomplete, we should skip the lower bound check.
            常量 hasEnoughArguments = argCount >= signature.minArgumentCount;
            返回 callIsIncomplete || hasEnoughArguments;
        }


        函数 getSpreadArgumentIndex(args: 只读数组_<表达式_>): 数字 {
            循环 (变量 i = 0; i < args.长度; i++) {
                常量 arg = args[i];
                如果 (arg && arg.种类 === 语法_.省略表达式_) {
                    返回 i;
                }
            }
            返回 -1;
        }

        函数 checkApplicableSignature(
            node: 调用族表达式_,
            args: 只读数组_<表达式_>,
            signature: 签名_,
            relation: 词典_<关系比较结果_>,
            excludeArgument: 真假[],
            reportErrors: 真假) {
            excludeArgument
            常量 headMessage = 诊断信息_.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
            常量 argCount = args.长度;
            循环 (变量 i = 0; i < argCount; i++) {
                常量 arg = getEffectiveArgument(node, args, i);
                // If the effective argument is '未定', then it is an argument that is present but is synthetic.
                如果 (arg === 未定 || arg.种类 !== 语法_.省略表达式_) {
                    // Check spread elements against rest 类型 (from arity check we know spread argument corresponds to a rest parameter)
                    常量 paramType = getTypeAtPosition(signature, i);
                    // If the effective argument 类型 is 未定, there is no synthetic 类型 for the argument.
                    // In that 若是, we should check the argument.
                    常量 argType = checkExpressionWithContextualType(arg!, paramType, excludeArgument && excludeArgument[i] ? identityMapper : 未定);
                    // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter),
                    // we obtain the regular 类型 of any object literal arguments because we may not have inferred complete
                    // parameter 类型组 yet and therefore excess property checks may yield false positives (see #17041).
                    常量 checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType;
                    // Use argument expression as error location when reporting errors
                    常量 errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg!) : 未定;
                    如果 (!checkTypeRelatedTo(checkArgType, paramType, relation, errorNode!, headMessage)) {
                        返回 为假;
                    }
                }
            }
            返回 为真;
        }

        函数 getRegularTypeOfObjectLiteral(类型: 类型_): 类型_ {
            如果 (!(isObjectLiteralType(类型) && 类型.标志 & 类型标志_.新字面量类型_)) {
                返回 类型;
            }
            常量 regularType = (<新鲜结构字面量类型_>类型).常规类型;
            如果 (regularType) {
                返回 regularType;
            }

            常量 resolved = <解析类型_>类型;
            常量 members = transformTypeOfMembers(类型, getRegularTypeOfObjectLiteral);

            常量 regularNew = createAnonymousType(resolved.符号!, members,  resolved.方法组!);

            regularNew.标志 = resolved.标志 & ~类型标志_.新字面量类型_;
            regularNew.对象标志 |= 对象标志_.字面量_;
            (<新鲜结构字面量类型_>类型).常规类型 = regularNew;
            返回 regularNew;
        }

        函数 transformTypeOfMembers(类型: 类型_, f: (propertyType: 类型_) => 类型_) {
            常量 members = 创建符号表();
            循环 (常量 property 属于 getPropertiesOfObjectType(类型)) {
                常量 original = getTypeOfSymbol(property);
                常量 updated = f(original);
                members.设置(property.名称, updated === original ? property : createSymbolWithType(property, updated));
            }
            返回 members;
        }

        函数 getEffectiveArgument(node: 调用族表达式_, args: 只读数组_<表达式_>, argIndex: 数字) {
            // For a decorator or the first argument of a tagged template expression we 返回 未定.
            如果 ((argIndex === 0 && node.种类 === 语法_.标记模板表达式_)) {
                返回 未定;
            }

            返回 args[argIndex];
        }

        函数 getEffectiveArgumentErrorNode(node: 调用族表达式_, argIndex: 数字, arg: 表达式_) {
            如果 (argIndex === 0 && node.种类 === 语法_.标记模板表达式_) {
                // For a the first argument of a tagged template expression, we use the template of the tag for error reporting.
                返回 node.模板;
            }
            否则 {
                返回 arg;
            }
        }

        函数 getTypeAtPosition(signature: 签名_, pos: 数字): 类型_ {
            返回 signature.具有剩余参数 ?
                pos < signature.参数.长度 - 1 ? getTypeOfParameter(signature.参数[pos]) : getRestTypeOfSignature(signature) :
                pos < signature.参数.长度 ? getTypeOfParameter(signature.参数[pos]) : 通用类型;
        }

        函数 getSignaturesOfStructuredType(类型: 类型_): 签名_[] {
            如果 (是指针类型(类型)) {
                类型 = 类型.基础类型
            }
            如果 (类型.标志 & 类型标志_.结构化类型_) {
                常量 resolved = resolveStructuredTypeMembers(<对象类型_>类型);
                返回 resolved.调用签名组 || 空数组
            }
            返回 空数组;
        }

        函数 resolveStructuredTypeMembers(类型: 对象类型_): 解析类型_ {
            如果 (!(<解析类型_>类型).成员) {
                如果 (类型.标志 & 类型标志_.对象_) {
                    如果 ((<对象类型_>类型).对象标志 & 对象标志_.引用_) {
                        解析类型引用成员(<类型引用_>类型);
                    }
                    如果 ((<对象类型_>类型).对象标志 & 对象标志_.结构_) {
                        解析结构类型成员(<结构类型_>类型);
                    }
                    否则 如果 ((<对象类型_>类型).对象标志 & 对象标志_.接口_) {
                        解析接口类型成员(<接口类型_>类型);
                    }
                    否则 如果 ((<对象类型_>类型).对象标志 & 对象标志_.程序_) {
                        解析程序类型成员(<程序类型_>类型)
                    }
                    否则 如果 ((<对象类型_>类型).对象标志 & 对象标志_.匿名_) {
                        解析匿名类型成员(<匿名类型_>类型)
                    }
                    否则 如果 ((<对象类型_>类型).对象标志 & 对象标志_.返回值_) {
                        解析返回值类型成员(<返回值类型_>类型);
                    }
                    否则 如果 ((<对象类型_>类型).对象标志 & 对象标志_.定义_) {
                        解析定义类型成员(<定义类型_>类型);
                    }
                }
            }
            返回 <解析类型_>类型;
        }

        函数 setStructuredTypeMembers(类型: 结构化类型_, 成员组: 符号表_, 方法组: 符号表_, 调用签名组: 签名_[]): 解析类型_ {
            (<解析类型_>类型).成员 = 成员组; // 成员是带名称的 符号表
            (<解析类型_>类型).属性组 = 转为属性数组(成员组);
            (<解析类型_>类型).方法组 = 方法组;
            (<解析类型_>类型).调用签名组 = 调用签名组;
            返回 <解析类型_>类型;
        }

        函数 转为属性数组(members: 符号表_): 符号_[] {
            变量 result: 符号_[];
            members.循环执行(符号 => {
                如果 (!result) result = [];
                如果 (符号.标志 & 符号标志_.属性_) {
                    result.压入(符号);
                }
            });
            返回 result! || 空数组;
        }

        函数 转为方法声明符号组(成员: 符号表_| 未定) {
            如果(!成员 || !成员.大小){
                返回 空数组
            }
            变量 result: 符号_[];
            成员.循环执行(符号 => {
                如果 (!result) result = [];
                变量 值声明 = 符号.值声明!
                如果 (值声明 && 是方法声明(值声明)) {
                    遍历子节点(值声明, 函数 a(n) {
                        如果 (是类型引用节点(n)) {
                            替换本体引用类型参数(n)
                            变量 类型实参 = n.类型实参
                            如果 (类型实参 && 类型实参.长度) {
                                循环 (变量 ii = 0; ii < 类型实参.长度; ii++) {
                                    变量 当前实参 = 类型实参[ii]
                                    如果 (是类型引用节点(当前实参)) {
                                        替换本体引用类型参数(当前实参)
                                    }
                                }
                            }
                        }
                        否则 {
                            遍历子节点(n, a)
                        }
                    })
                }
                result.压入(符号);
            });
            返回 result! || 空数组;
        }

        函数 替换本体引用类型参数(tn: 类型引用节点_) {
            变量 名称 = tn.类型名
            如果 (是限定名(名称)&& 是标识符(名称.左侧) && 名称.左侧.文本 === '本体') tn.类型名 = 名称.右侧
        }

        函数 解析定义类型成员(类型: 定义类型_) {
            变量 方法符号表 = 类型.符号!.父符号!.方法集合!.获取(类型.符号!.名称)
            变量 基础类型 = (<定义类型_>类型).基础类型
            如果 (是指针类型(基础类型)) {
                基础类型 = 基础类型.基础类型
            }
            变量 成员 = 空符号表
            如果 (基础类型.标志 & 类型标志_.对象_) {
                成员 = resolveStructuredTypeMembers(<对象类型_>基础类型).成员
            }
            返回 setStructuredTypeMembers(类型, 成员, 方法符号表 || 空符号表, 空数组)
        }
        
        函数 instantiateSignatures(signatures: 签名_[], 映射: 类型映射_) {
            返回 instantiateList(signatures, 映射, instantiateSignature);
        }


        函数 解析匿名类型成员(类型: 匿名类型_) {
            常量 符号 = 类型.符号!;
            如果 (类型.目标) {
                常量 members = createInstantiatedSymbolTable(getPropertiesOfObjectType(类型.目标), 类型.映射!);
                常量 callSignatures = instantiateSignatures(getSignaturesOfType(类型.目标), 类型.映射!);                
                setStructuredTypeMembers(类型, members, 空符号表, callSignatures 转为 []);
            }
            否则 如果 (符号.标志 & 符号标志_.类型字面量_) {
                常量 members = 符号.成员!;
                变量 callSignatures: 签名_[] = 空数组
                如果(members){
                    callSignatures =  getSignaturesOfSymbol(members.获取('@调用')!) || 空数组
                }
                setStructuredTypeMembers(类型, members, 空符号表, callSignatures 转为 []);
            }
            否则 {
                如果 (符号.标志 & (符号标志_.函数_ | 符号标志_.方法_)) { 
                    setStructuredTypeMembers(类型, 空符号表, 空符号表, getSignaturesOfSymbol(符号));
                }
            }
            返回 类型
        }

        函数 解析程序类型成员(类型: 程序类型_): 解析类型_ {
            常量 符号 = getMergedSymbol(类型.符号!);
            变量 成员 = 符号.成员!;
            (<解析类型_>类型).成员 = 成员
            返回 <解析类型_>类型
        }

        函数 解析返回值类型成员(类型: 返回值类型_) {
            变量 成员 = 类型.符号!.成员
            变量 调用签名: 签名_[] = []
            如果 (成员) {
                成员.循环执行(s => {
                    变量 签名组 = getSignaturesOfSymbol(s)
                    添加范围(调用签名, 签名组)
                })
                返回 setStructuredTypeMembers(类型, 成员, 空符号表, 空数组)
            }
            返回 <解析类型_>类型
        }

        函数 resolveDeclaredMembers(类型: 结构类型_): 结构类型包括声明成员_ {
            如果 (!(<结构类型包括声明成员_>类型).声明属性组) {
                常量 符号 = 类型.符号!;
                常量 members = 符号.成员 || 空符号表;
                变量 方法符号表 = 类型.符号!.父符号!.方法集合!.获取(类型.符号!.名称);
                (<结构类型包括声明成员_>类型).声明属性组 = 转为属性数组(members);
                (<结构类型包括声明成员_>类型).方法组 = 方法符号表 || 空符号表
            }
            返回 <结构类型包括声明成员_>类型;
        }

        函数 解析类型引用成员(类型: 类型引用_): 解析类型_ {
            常量 source = resolveDeclaredMembers(类型.目标);
            常量 typeParameters = source.类型参数
            常量 类型实参 = 类型.类型实参!
            返回 resolveObjectTypeMembers(类型, source, typeParameters, 类型实参)
        }

        函数 resolveObjectTypeMembers(类型: 对象类型_, source: 结构类型包括声明成员_, typeParameters: 类型参数_[], typeArguments: 类型_[]) {
            变量 映射: 类型映射_;
            变量 members: 符号表_;
            变量 方法组: 符号表_;
            如果 (rangeEquals(typeParameters, typeArguments, 0, typeParameters.长度)) {
                映射 = identityMapper;
                members = source.符号 && source.符号.成员 ? source.符号.成员! : 创建符号表(source.声明属性组);
                方法组 = source.方法组 || source.符号!.父符号!.方法集合!.获取(source.符号!.名称);
            }
            否则 {
                映射 = createTypeMapper(typeParameters, typeArguments);
                members = createInstantiatedSymbolTable(source.声明属性组, 映射);
                方法组 = createInstantiatedSymbolTable(转为方法声明符号组(source.方法组), 映射);
            }
            返回 setStructuredTypeMembers(类型, members, 方法组, 空数组);
        }

        函数 解析结构类型成员(类型: 结构类型_): 解析类型_ {
            变量 方法符号表 = 空符号表
            如果 (类型.符号!.父符号!.方法集合!) {
                方法符号表 = 类型.符号!.父符号!.方法集合!.获取(类型.符号!.名称) || 空符号表
            }
            返回 setStructuredTypeMembers(类型, 类型.符号!.成员 || 空符号表, 方法符号表, 空数组)
        }

        函数 解析接口类型成员(类型: 接口类型_) {
            返回 setStructuredTypeMembers(类型, 空符号表, 类型.符号!.成员 || 空符号表, 空数组)
        }

        /**
         * Return the signatures of the given 种类 in the given 类型. Creates synthetic union signatures when necessary and
         * maps primitive 类型组 and 类型 parameters are to their apparent 类型组.
         */
        函数 getSignaturesOfType(类型: 类型_): 签名_[] {
            返回 getSignaturesOfStructuredType(getApparentType(类型));
        }

        /**
         * 应该叫获取基础类型
         */
        函数 getApparentType(类型: 类型_): 类型_ {
            常量 t = 类型.标志 & 类型标志_.类型参数_ ? getBaseConstraintOfType(类型) || emptyObjectType : 类型;
            返回 t || 通用类型
        }

        函数 是类型声明类型(类型: 类型_):类型 作为 定义类型_ {
            返回 !!(类型.标志 & 类型标志_.对象_ && (<对象类型_>类型).对象标志 & 对象标志_.定义_)
        }

        函数 是指针类型(类型: 类型_): 类型 作为 指针类型_ {
            返回 !!(类型.标志 & 类型标志_.复合类型_ && (<复合类型_>类型).复合标志 & 复合标志_.指针类型_)
        }

        函数 getSignaturesOfSymbol(符号: 符号_): 签名_[] {
            如果 (!符号) 返回 空数组;
            常量 result: 签名_[] = [];
            循环 (变量 i = 0; i < 符号.声明组!.长度; i++) {
                常量 node = 符号.声明组![i];
                假如 (node.种类) {
                    若是 语法_.函数类型_:
                    若是 语法_.函数签名_:
                    若是 语法_.创建函数签名_:
                    若是 语法_.函数声明_:
                    若是 语法_.方法声明_:
                    若是 语法_.方法签名_:
                    若是 语法_.函数表达式_:
                    若是 语法_.箭头函数_:
                        result.压入(getSignatureFromDeclaration(<签名声明_>node));
                }
            }
            返回 result;
        }

        函数 getSignatureFromDeclaration(declaration: 签名声明_): 签名_ {
            常量 links = getNodeLinks(declaration);
            如果 (!links.resolvedSignature) {
                常量 parameters: 符号_[] = [];
                变量 minArgumentCount = 0;
                循环 (变量 i = 0; i < declaration.参数!.长度; i++) {
                    常量 param = declaration.参数![i];
                    变量 paramSymbol = param.符号;
                    parameters.压入(paramSymbol);

                    常量 isOptionalParameter = 是剩余参数(param)
                    如果 (!isOptionalParameter) {
                        minArgumentCount = parameters.长度;
                    }
                }

                常量 returnType = getSignatureReturnTypeFromDeclaration(declaration);
                常量 hasRestLikeParameter = 具有剩余参数(declaration);
                常量 typeParameters = getTypeParametersFromDeclaration(declaration);
                links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, minArgumentCount, hasRestLikeParameter);
            }
            返回 links.resolvedSignature;
        }

        函数 getTypeParametersFromDeclaration(declaration: 声明包括类型参数_): 类型参数_[] {
            变量 result: 类型参数_[];
            循环执行(declaration.类型参数, node => {
                常量 tp = getDeclaredTypeOfTypeParameter(node.符号);
                result = 附加如果唯一(result, tp);
            });
            返回 result!;
        }

        函数 getEffectiveReturnTypeNode(node: 签名声明_): 返回值声明属性组_ | 未定 {
            返回 node.类型;
        }

        函数 getSignatureReturnTypeFromDeclaration(declaration: 签名声明_) {
            常量 返回声明 = getEffectiveReturnTypeNode(declaration);
            如果 (返回声明 && 返回声明.声明组 && 返回声明.声明组.长度) {
                如果 (返回声明.声明组.长度 === 1) {
                    常量 唯一的声明 = 返回声明.声明组[0]
                    如果 (是类型节点(唯一的声明)) {
                        返回 getTypeFromTypeNode(唯一的声明)
                    }
                }
                常量 返回值符号 = declaration.本地组!.获取('@返回值')
                返回 创建对象类型(对象标志_.返回值_, 返回值符号)
            }
            否则 {
                返回 无值类型
            }
        }   

        函数 resolveTaggedTemplateExpression(node: 标记模板表达式_, candidatesOutArray: 签名_[]): 签名_ {
            常量 tagType = checkExpression(node.标签);
            常量 apparentType = getApparentType(tagType);

            如果 (apparentType === 未知类型) {
                // Another error has already been reported
                返回 resolveErrorCall(node);
            }

            常量 callSignatures = getSignaturesOfType(apparentType);

            如果 (!callSignatures.长度) {
                error(node, 诊断信息_.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, 'typeToString(apparentType)');
                返回 resolveErrorCall(node);
            }

            返回 resolveCall(node, callSignatures, candidatesOutArray);
        }

        函数 resolveSignature(node: 调用族表达式_, 候选输出数组?: 签名_[]): 签名_ {
            假如 (node.种类) {
                若是 语法_.调用表达式_:
                    返回 resolveCallExpression(node, 候选输出数组!);
                若是 语法_.标记模板表达式_:
                    返回 resolveTaggedTemplateExpression(node, 候选输出数组!);
                若是 语法_.创建表达式_:
                    // TODO 创建表达式
                    返回 {} 转为 签名_
            }
            调试_.断言不及(node, "Branch in 'resolveSignature' should be unreachable.");
        }

        函数 checkCallExpression(node: 调用表达式_ | 创建表达式_): 类型_ {
            常量 signature = getResolvedSignature(node);
            常量 returnType = getReturnTypeOfSignature(signature);
            返回 returnType;
        }

        函数 getReturnTypeOfSignature(signature: 签名_): 类型_ {
            如果 (!signature.resolvedReturnType) {
                如果 (!pushTypeResolution(signature, 类型系统属性名称_.解析的返回类型_)) {
                    返回 未知类型
                }
                变量 类型!: 类型_;
                如果 (signature.目标) {
                    类型 = instantiateType(getReturnTypeOfSignature(signature.目标), signature.映射!);
                }
                否则 如果 (signature.unionSignatures) {
                    类型 = getUnionType(词典(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
                }
                否则 如果((<函数声明_>signature.declaration)&& (<函数声明_>signature.declaration).类型) {
                    类型 = getTypeFromTypeNode((<函数声明_>signature.declaration).类型!);
                }
                如果 (!popTypeResolution()) {
                    类型 = 无值类型;
                }
                signature.resolvedReturnType = 类型 || 无值类型;
            }
            返回 signature.resolvedReturnType;
        }

        函数 getResolvedSignature(node: 调用族表达式_, 候选输出数组?: 签名_[]): 签名_ {
            常量 links = getNodeLinks(node);
            // If getResolvedSignature has already been called, we will have cached the resolvedSignature.
            // However, it is possible that either candidatesOutArray was not passed in the first time,
            // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work
            // to correctly fill the candidatesOutArray.
            常量 cached = links.resolvedSignature;
            如果 (cached && cached !== 解析中签名 && !候选输出数组) {
                返回 cached;
            }
            links.resolvedSignature = 解析中签名;
            常量 result = resolveSignature(node, 候选输出数组);
            // If signature resolution originated in control flow 类型 analysis (for example to compute the
            // assigned 类型 in a flow assignment) we don't cache the result as it may be based on temporary
            // types from the control flow analysis.
            links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
            返回 result;
        }

        函数 checkExpressionWithContextualType(node: 表达式_, contextualType: 类型_, contextualMapper: 类型映射_ | 未定): 类型_ {
            常量 context = node;
            常量 saveContextualType = context.上下文类型_
            常量 saveContextualMapper = context.contextualMapper;
            context.上下文类型_ = contextualType;
            context.contextualMapper = contextualMapper;
            常量 checkMode = contextualMapper === identityMapper ? 检查模式_.跳过上下文相关_ :
                contextualMapper ? 检查模式_.推理的_ : 检查模式_.上下文的_;
            常量 result = checkExpression(node, checkMode);
            context.上下文类型_ = saveContextualType;
            context.contextualMapper = saveContextualMapper;
            返回 result;
        }

        函数 checkExpressionWorker(n: 表达式_, checkMode: 检查模式_): 类型_ {
            假如 (n.种类) {
                若是 语法_.标识符_:
                    返回 checkIdentifier(<标识符_>n);
                若是 语法_.无替换模板字面量_:
                若是 语法_.文本字面量_:
                    返回 创建文本字面量类型((<文本字面量_>n).文本.长度 + 1)
                若是 语法_.数字字面量_:
                    返回 检查数字字面量表达式(<数字字面量_>n)
                若是 语法_.真_:
                    返回 真类型
                若是 语法_.假_:
                    返回 假类型
                若是 语法_.模板表达式_:
                    返回 checkTemplateExpression(<模板表达式_>n)
                若是 语法_.未定_:
                    返回 未定类型
                若是 语法_.正则表达式字面量_:
                    // TODO 这个还未实现
                    返回 文本类型
                若是 语法_.数组字面量表达式_:
                    返回 检查数组字面量表达式(<数组字面量表达式_>n)
                若是 语法_.结构字面量表达式_:
                    返回 检查结构字面量表达式(<结构字面量表达式_>n)
                若是 语法_.取值表达式_:
                    返回 checkExpression((<取址表达式_>n).算子)
                若是 语法_.取址表达式_:
                    返回 创建指针类型(checkExpression((<取址表达式_>n).算子))
                若是 语法_.属性访问表达式_:
                    返回 checkPropertyAccessExpression(<属性访问表达式_>n)
                若是 语法_.元素访问表达式_:
                    返回 检查元素访问表达式(<元素访问表达式_>n)
                若是 语法_.新建表达式_:
                    返回 检查新建表达式(<新建表达式_>n)
                若是 语法_.调用表达式_:
                若是 语法_.创建表达式_:
                    返回 checkCallExpression(<创建表达式_ | 调用表达式_>n)
                若是 语法_.标记模板表达式_:
                    返回 checkTaggedTemplateExpression(<标记模板表达式_>n)
                若是 语法_.括号表达式_:
                    返回 checkExpression((<括号表达式_>n).表达式)
                若是 语法_.函数表达式_:
                若是 语法_.箭头函数_:
                    返回 检查函数表达式或箭头函数表达式(<函数表达式_ | 箭头函数_>n, checkMode)
                若是 语法_.类型查询表达式_:
                    返回 未定类型
                若是 语法_.类型断言表达式_:
                    返回 检查类型断言表达式(<类型断言表达式_>n)
                若是 语法_.类型转换表达式_:
                    返回 检查类型转换表达式(<类型转换表达式_>n)
                若是 语法_.无值表达式_:
                    返回 无值类型
                若是 语法_.前缀一元表达式_:
                若是 语法_.后缀一元表达式_:
                    返回 检查前缀或后缀表达式(<前缀一元表达式_ | 后缀一元表达式_>n)
                若是 语法_.二元表达式_:
                    返回 checkBinaryExpression(<二元表达式_>n, checkMode) || 未知类型
                若是 语法_.条件表达式_:
                    返回 checkConditionalExpression(<条件表达式_>n)
                若是 语法_.展开元素_:
                    返回 检查展开元素类型(<展开元素_>n)
            }
            返回 未知类型;
        }

        函数 检查新建表达式(n: 新建表达式_) {
            变量 类型 = getTypeFromTypeNode(n.类型参数)
            返回 创建指针类型(类型)
        }

        函数 checkTemplateExpression(n: 模板表达式_): 类型_ {
            循环执行(n.模板跨度组, 跨度 => {
                checkExpression(跨度.表达式);
            });
            返回 文本类型
        }

        函数 检查函数表达式或箭头函数表达式(n: 函数表达式_ | 箭头函数_, checkMode: 检查模式_) {
            // The identityMapper object is used to indicate that function expressions are wildcards
            如果 (checkMode === 检查模式_.跳过上下文相关_ && isContextSensitive(n)) {
                返回 anyFunctionType;
            }

            常量 links = getNodeLinks(n);
            常量 类型 = getTypeOfSymbol(n.符号);

            // Check 如果 function expression is contextually typed and assign parameter types 如果 so.
            如果 (!(links.标志! & NodeCheckFlags.ContextChecked)) {
                常量 contextualSignature = getContextualSignature(n);
                // If a 类型 check is started at a function expression that is an argument of a function call, obtaining the
                // contextual 类型 may recursively get back to here during overload resolution of the call. If so, we will have
                // already assigned contextual types.
                如果 (!(links.标志! & NodeCheckFlags.ContextChecked)) {
                    links.标志! |= NodeCheckFlags.ContextChecked;
                    如果 (contextualSignature) {
                        常量 signature = getSignaturesOfType(类型)[0];
                        如果 (isContextSensitive(n)) {
                            常量 contextualMapper = getContextualMapper(n)!;
                            如果 (checkMode === 检查模式_.推理的_) {
                                inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper);
                            }
                            常量 instantiatedContextualSignature = contextualMapper === identityMapper ?
                                contextualSignature : instantiateSignature(contextualSignature, contextualMapper);
                            assignContextualParameterTypes(signature, instantiatedContextualSignature);
                        }
                    }
                    checkSignatureDeclaration(n);
                }
            }
            返回 类型;
        }
        
        函数  inferFromAnnotatedParameters(signature: 签名_, context: 签名_, mapper: 类型映射_ ){
            常量 len = signature.参数.长度 - (signature.具有剩余参数 ? 1 : 0);
            循环 (let i = 0; i < len; i++) {
                常量 declaration = <参数声明_>signature.参数[i].值声明;
                如果 (declaration.类型) {
                    常量 typeNode = getEffectiveTypeAnnotationNode(declaration);
                    如果 (typeNode) {
                        inferTypes((<推断上下文_>mapper).inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i));
                    }
                }
            }
        }
        
        函数 assignContextualParameterTypes(signature: 签名_, context: 签名_) {
            signature.typeParameters = context.typeParameters;
            常量 len = signature.参数.长度 - (signature.具有剩余参数 ? 1 : 0);
            循环 (变量 i = 0; i < len; i++) {
                常量 parameter = signature.参数[i];
                如果 (!getEffectiveTypeAnnotationNode(<参数声明_>parameter.值声明)) {
                    常量 contextualParameterType = getTypeAtPosition(context, i);
                    assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
                }
            }
            如果 (signature.具有剩余参数 && isRestParameterIndex(context, signature.参数.长度 - 1)) {
                // parameter might be a transient symbol generated by use of `arguments` in the function body.
                常量 参数 = 最后或未定义(signature.参数)!;
                如果 (isTransientSymbol(参数) || !getEffectiveTypeAnnotationNode(<参数声明_>参数.值声明)) {
                    常量 contextualParameterType = getTypeOfSymbol(最后或未定义(context.参数)!);
                    assignTypeToParameterAndFixTypeParameters(参数, contextualParameterType);
                }
            }
        }
        
        函数 isTransientSymbol(symbol: 符号_): symbol 作为 临时符号_ {
            返回 (symbol.标志 & 符号标志_.临时的_) !== 0;
        }

        函数 assignTypeToParameterAndFixTypeParameters(parameter: 符号_, contextualType: 类型_) {
            常量 links = getSymbolLinks(parameter);
            如果 (!links.类型) {
                links.类型 = contextualType;
            }
        }

        函数 checkTaggedTemplateExpression(node: 标记模板表达式_): 类型_ {
            返回 getReturnTypeOfSignature(getResolvedSignature(node));
        }

        函数 检查展开元素类型(n: 展开元素_) {
            变量 数组类别类型 = checkExpression(n.表达式)
            返回 (<数组类型_>数组类别类型).基础类型
        }

        函数 checkConditionalExpression(node: 条件表达式_, checkMode?: 检查模式_): 类型_ {
            checkExpression(node.条件);
            常量 type1 = checkExpression(node.当为真, checkMode);
            常量 type2 = checkExpression(node.当为假, checkMode);
            返回 getUnionType([type1, type2], UnionReduction.Subtype);
        }

        函数 检查前缀或后缀表达式(n: 前缀一元表达式_ | 后缀一元表达式_) {
            返回 checkExpression(n.算子)
        }

        函数 检查类型断言表达式(n: 类型断言表达式_) {
            常量 容器符号 = createSymbol(符号标志_.结构_, '@返回值')
            容器符号.成员 = 创建符号表()
            常量 符号1 = createSymbol(符号标志_.属性_, '@返回值_0')
            符号1.声明组 = [n.类型]
            符号1.值声明 = n.类型
            常量 符号2 = createSymbol(符号标志_.属性_, '@返回值_1')
            常量 真假声明 = <类型节点_>创建节点(语法_.真假_, -1, -1)
            符号2.声明组 = [真假声明]
            符号2.值声明 = 真假声明
            容器符号.成员.设置('@返回值_0', 符号1)
            容器符号.成员.设置('@返回值_1', 符号2)
            返回 创建对象类型(对象标志_.返回值_, 容器符号)
        }

        函数 检查类型转换表达式(n: 类型转换表达式_) {
            变量 类型节点类型 = getTypeFromTypeNode(n.类型)
            变量 表达式类型 = checkExpression(n.表达式)
            // 检查是否是可转换身份
            类型节点类型
            表达式类型
            返回 类型节点类型
        }

        函数 是数组类型(t: 类型_): t 作为 数组类型_ {
            返回 !!((t.标志 & 类型标志_.复合类型_) && ((<复合类型_>t).复合标志 & 复合标志_.数组类型_))
        }

        函数 是列表类型(t: 类型_): t 作为 列表类型_ {
            返回 !!((t.标志 & 类型标志_.复合类型_) && ((<复合类型_>t).复合标志 & 复合标志_.列表类型_))
        }

        函数 是通信类型(t: 类型_): t 作为 通信类型_ {
            返回 !!((t.标志 & 类型标志_.复合类型_) && ((<复合类型_>t).复合标志 & 复合标志_.通信类型_))
        }

        函数 是只读通信类型(t: 类型_): t 作为 只读通信类型_ {
            返回 !!((t.标志 & 类型标志_.复合类型_) && ((<复合类型_>t).复合标志 & 复合标志_.只读通信类型_))
        }

        函数 是词典类型(t: 类型_): t 作为 词典类型_ {
            返回 !!(t.标志 & 类型标志_.词典类型_)
        }

        函数 是文本类型(t: 类型_): t 作为 词典类型_ {
            返回 !!(t.标志 & 类型标志_.文本类型_)
        }

        函数 检查数字字面量表达式(n: 数字字面量_) {
            变量 值 = 0
            变量 是整数 = 为假
            变量 是虚数 = 为假
            如果 (n.数字字面量标志 & 令牌标志_.虚部_) {
                是虚数 = 为真
                值 = +(n.文本.分切(0, -1))
            }
            否则 {
                值 = +(n.文本)
                是整数 = 数字_.是整数(值)
            }
            如果 (是整数) {
                如果 (值 >= 数字字面量值范围.获取('整数8')!.最小 && 值 <= 数字字面量值范围.获取('整数8')!.最大) {
                    返回 整数类型_8
                }
                如果 (值 >= 数字字面量值范围.获取('整数16')!.最小 && 值 <= 数字字面量值范围.获取('整数16')!.最大) {
                    返回 整数类型_16
                }
                如果 (值 >= 数字字面量值范围.获取('整数32')!.最小 && 值 <= 数字字面量值范围.获取('整数32')!.最大) {
                    返回 整数类型_32
                }
                如果 (值 >= 数字字面量值范围.获取('整数64')!.最小 && 值 <= 数字字面量值范围.获取('整数64')!.最大) {
                    返回 整数类型_64
                }
                如果 (值 >= 0 && 值 <= 数字字面量值范围.获取('整数64')!.最大) {
                    返回 正整数类型_64
                }
                error(n, 诊断信息_.整数值溢出)
                返回 整数类型_64
            }
            否则 如果 (是虚数!) {
                变量 a = 数字字面量值范围.获取('小数32')!.最小!
                变量 b = 数字字面量值范围.获取('小数32')!.最大!
                如果 (值 >= a && 值 <= b) {
                    返回 虚数类型_32
                }
                如果 (值 >= 数字字面量值范围.获取('小数32')!.最小 && 值 <= 数字字面量值范围.获取('小数32')!.最大) {
                    返回 虚数类型_32
                }
                如果 (值 >= 数字字面量值范围.获取('小数64')!.最小 && 值 <= 数字字面量值范围.获取('小数64')!.最大) {
                    返回 虚数类型_64
                }
                error(n, 诊断信息_.浮点值溢出)
                返回 虚数类型_64
            }
            否则 {
                变量 a = 数字字面量值范围.获取('小数32')!.最小!
                变量 b = 数字字面量值范围.获取('小数32')!.最大!
                如果 (值 >= a && 值 <= b) {
                    返回 小数类型_32
                }
                如果 (值 >= 数字字面量值范围.获取('小数32')!.最小 && 值 <= 数字字面量值范围.获取('小数32')!.最大) {
                    返回 小数类型_32
                }
                如果 (值 >= 数字字面量值范围.获取('小数64')!.最小 && 值 <= 数字字面量值范围.获取('小数64')!.最大) {
                    返回 小数类型_64
                }
                error(n, 诊断信息_.浮点值溢出)
                返回 小数类型_64
            }
        }

        函数 检查数组字面量表达式(n: 数组字面量表达式_): 类型_ {
            变量 类型 = getTypeFromTypeNode(n.元素类型)
            如果 (是数组类型(类型)) {
                循环 (变量 i = 0; i < n.元素.长度; i++) {
                    变量 当前 = n.元素[i]
                    变量 元素类型 = checkExpression(当前);
                    checkTypeAssignableTo(元素类型, 类型.基础类型, 当前)
                }
                如果 (!类型.长度) {
                    类型.长度 = n.元素.长度
                }
                如果 (类型.长度 < n.元素.长度) {
                    // 错误
                }
            }
            返回 类型
        }

        函数 检查结构字面量表达式(n: 结构字面量表达式_) {
            变量 约束类型 = getTypeFromTypeNode(n.结构体类型名)
            如果 (是指针类型(约束类型)) {
                约束类型 = 约束类型.基础类型
            }
            变量 解析约束类型!: 解析类型_
            如果 (约束类型.标志 & 类型标志_.对象_) {
                解析约束类型 = resolveStructuredTypeMembers(<对象类型_>约束类型);
            }
            变量 属性组 = 创建符号表()
            循环 (变量 i = 0; i < n.属性组.长度; i++) {
                变量 当前属性 = n.属性组[i]
                变量 约束属性类型 = getTypeOfPropertyOfType(约束类型, 当前属性.名称.文本)
                变量 属性类型 = getTypeOfSymbol(当前属性.符号)
                变量 ok = checkTypeAssignableTo(属性类型, 约束属性类型, 当前属性)
                如果 (ok) {
                    变量 临时 = getTypeOfSymbol(当前属性.符号)
                    变量 临时符号 = createSymbol(符号标志_.属性_, 当前属性.符号.名称)
                    临时符号.声明组 = 当前属性.符号.声明组
                    临时符号.父符号 = 当前属性.符号.父符号;
                    如果 (当前属性.符号.值声明) {
                        临时符号.值声明 = 当前属性.符号.值声明;
                    }
                    临时符号.类型 = 临时;
                    临时符号.目标 = 当前属性.符号;
                    当前属性.符号 = 临时符号;
                    属性组.设置(当前属性.符号.名称, 临时符号)
                }
            }

            返回 创建对象字面量类型()

            函数 创建对象字面量类型() {
                变量 方法表 = 解析约束类型.方法组 || 空符号表
                返回 createAnonymousType(n.符号, 属性组, 方法表)
            }

        }

        函数 初始化类型检查() {
            变量 符号组: 词典_<符号_> = 创建词典()
            循环 (常量 文件 属于 主机.获取源文件组()) {
                绑定源文件(文件, 主机);
                如果 (文件.程序集.名称 === '@全局') {
                    mergeSymbolTable(globals, 文件.程序集.成员!)
                }
                否则 {
                    如果 (!符号组.具有(文件.程序集.名称)) {
                        符号组.设置(文件.程序集.名称, 文件.程序集)
                    }
                    否则 {
                        mergeSymbol(符号组.获取(文件.程序集.名称)!, 文件.程序集)
                    }
                }
            }
        }

        函数 errorUnusedLocal(declaration: 声明_, name: 文字) {
            常量 node = 获取声明名称(declaration) || declaration;
            如果 (isIdentifierThatStartsWithUnderScore(node)) {
                常量 declaration = 获取根声明(node.父节点);
                如果 ((declaration.种类 === 语法_.变量声明_ && 是循环属于语句(declaration.父节点!.父节点))) {
                    返回;
                }
            }
            diagnostics.添加(创建诊断从节点跨度(获取节点的源文件(declaration), declaration, node, 诊断信息_._0_is_declared_but_its_value_is_never_read, name));
        }

        函数 isIdentifierThatStartsWithUnderScore(node: 节点_) {
            返回 是标识符(node) && node.文本.字符代码在(0) === 字符_._;
        }

        函数 检查源码文件未使用导入成员(n: 源文件_): 无值 {
            如果 (!(n.标志 & 节点标志_.环境_)) {
                // Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
                常量 未使用导入: 声明_[] = [];
                如果 (n.是声明文件) 返回;

                n.本地组!.循环执行(本地符号 => {
                    如果 (本地符号.是被引用的) 返回;
                    如果 (!!(本地符号.标志 & 符号标志_.别名_)) {
                        循环 (常量 declaration 属于 本地符号.声明组!) {
                            如果 (declaration.种类 === 语法_.导入从成员_) {
                                未使用导入.压入(declaration)
                            }
                            如果 (declaration.种类 === 语法_.导入成员_) {
                                未使用导入.压入(declaration)
                            }
                        }
                    }
                });
                未使用导入.循环执行(_声明 => {
                    errorUnusedLocal(_声明, 获取声明名称(_声明)!.名称!.文本)
                });
            }
        }

        函数 检查本地未使用标识符和参数(node: 节点_): 无值 {
            如果 (!(node.标志 & 节点标志_.环境_)) {

                node.本地组!.循环执行(local => {
                    如果 (!local.是被引用的) {
                        如果 (local.值声明 && 获取根声明(local.值声明).种类 === 语法_.参数_) {
                            常量 name = 获取声明名称(local.值声明)!;
                            error(name, 诊断信息_._0_is_declared_but_its_value_is_never_read, symbolName(local));
                        }
                        否则 {
                            循环执行(local.声明组, d => errorUnusedLocal(d, symbolName(local)));
                        }
                    }
                });
            }
        }

        函数 registerForUnusedIdentifiersCheck(node: 节点_) {
            如果 (deferredUnusedIdentifierNodes) {
                deferredUnusedIdentifierNodes.压入(node);
            }
        }

        函数 checkUnusedIdentifiers() {
            如果 (deferredUnusedIdentifierNodes) {
                循环 (常量 node 属于 deferredUnusedIdentifierNodes) {
                    假如 (node.种类) {
                        若是 语法_.源文件_:
                            检查源码文件未使用导入成员(<源文件_>node);
                            跳出;
                        若是 语法_.块_:
                        若是 语法_.若是块_:
                        若是 语法_.循环语句_:
                        若是 语法_.循环属于语句_:
                            检查本地未使用标识符和参数(node);
                            跳出;
                        若是 语法_.函数表达式_:
                        若是 语法_.函数声明_:
                        若是 语法_.箭头函数_:
                        若是 语法_.方法声明_:
                            如果 ((<函数族声明_>node).主体) {
                                检查本地未使用标识符和参数(<函数族声明_>node);
                            }
                            跳出;
                        默认:
                            调试_.失败("节点_ should not have been registered 循环 unused identifiers check");
                    }
                }
            }
        }

        函数 checkEnumDeclaration(n: 枚举声明_) {
            n
        }

        函数 hasNonCircularBaseConstraint(类型: 可实例化类型_): 真假 {
            返回 getResolvedBaseConstraint(类型) !== 循环自身约束类型;
        }


        函数 hasNonCircularTypeParameterDefault(typeParameter: 类型参数_) {
            返回 getResolvedTypeParameterDefault(typeParameter) !== 循环自身约束类型;
        }

        /**
         * Push an entry on the 类型 resolution stack. If an entry with the given 目标 and the given property name
         * is already on the stack, and no entries in between already have a 类型, then a circularity has occurred.
         * In this case, the result values of the existing entry and all entries pushed after it are changed to false,
         * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned.
         * In order to see 如果 the same query has already been done before, the 目标 object and the propertyName both
         * must match the one passed in.
         *
         * @param 目标 The 符号, 类型, or signature whose 类型 is being queried
         * @param propertyName The property name that should be used to query the 目标 for its 类型
         */
        函数 pushTypeResolution(目标: 类型系统条目_, propertyName: 类型系统属性名称_): 真假 {
            常量 resolutionCycleStartIndex = findResolutionCycleStartIndex(目标, propertyName);
            如果 (resolutionCycleStartIndex >= 0) {
                // A cycle was found
                常量 长度 = 解析的目标组.长度;
                循环 (变量 i = resolutionCycleStartIndex; i < 长度; i++) {
                    解析的结果组[i] = 为假;
                }
                返回 为假;
            }
            解析的目标组.压入(目标);
            解析的结果组.压入(/*items*/ 为真);
            解析的属性名称组.压入(propertyName);
            返回 为真;
        }

        函数 findResolutionCycleStartIndex(目标: 类型系统条目_, propertyName: 类型系统属性名称_): 数字 {
            循环 (变量 i = 解析的目标组.长度 - 1; i >= 0; i--) {
                如果 (hasType(解析的目标组[i], 解析的属性名称组[i])) {
                    返回 -1;
                }
                如果 (解析的目标组[i] === 目标 && 解析的属性名称组[i] === propertyName) {
                    返回 i;
                }
            }

            返回 -1;
        }

        函数 hasType(目标: 类型系统条目_, propertyName: 类型系统属性名称_): 类型_ | 真假 | 未定 {
            如果 (propertyName === 类型系统属性名称_.类型_) {
                返回 getSymbolLinks(<符号_>目标).类型;
            }
            如果 (propertyName === 类型系统属性名称_.声明的类型_) {
                返回 getSymbolLinks(<符号_>目标).declaredType;
            }
            如果 (propertyName === 类型系统属性名称_.解析的返回类型_) {
                返回 (<签名_>目标).resolvedReturnType;
            }
            如果 (propertyName === 类型系统属性名称_.解析的基约束_) {
                常量 bc = (<类型参数_ | 联合或交叉类型_>目标).解析基约束;
                返回 bc && bc !== 循环自身约束类型;
            }
            调试_.失败("Unhandled TypeSystemPropertyName " + propertyName);
        }
        
        函数 getTypeWithThisArgument(类型: 类型_, thisArgument?: 类型_, needApparentType?: 真假): 类型_ {
            如果 (getObjectFlags(类型) & 对象标志_.引用_) {
                常量 target = (<类型引用_>类型).目标;
                常量 类型实参 = (<类型引用_>类型).类型实参!;
                如果 (长度(target.类型参数) === 长度(类型实参)) {
                    常量 ref = createTypeReference(target, 组合(类型实参!, [thisArgument! || target.thisType!]));
                    返回 needApparentType ? getApparentType(ref) : ref;
                }
            }
            否则 如果 (类型.标志 & 类型标志_.交叉_) {
                返回 getIntersectionType(词典((<交叉类型_>类型).类型组, t => getTypeWithThisArgument(t, thisArgument, needApparentType)));
            }
            返回 needApparentType ? getApparentType(类型) : 类型;
        }

        /**
         * Return the resolved base constraint of a 类型 variable. The noConstraintType singleton is returned 如果 the
         * 类型 variable has no constraint, and the circularConstraintType singleton is returned 如果 the constraint
         * circularly references the 类型 variable.
         */
        函数 getResolvedBaseConstraint(类型: 可实例化类型_ | 联合或交叉类型_ ): 类型_ {
            变量 circular: 真假;
            如果 (!类型.解析基约束) {
                常量 constraint = getBaseConstraint(类型);
                类型.解析基约束 = circular! ? 循环自身约束类型  : getTypeWithThisArgument(constraint || 无约束类型, 类型);
            }
            返回 类型.解析基约束;

            函数 getBaseConstraint(t: 类型_): 类型_ {
                如果 (!pushTypeResolution(t, 类型系统属性名称_.解析的基约束_)) {
                    circular = 为真;
                    返回 未定!;
                }
                常量 result = computeBaseConstraint(t);
                如果 (!popTypeResolution()) {
                    circular = 为真;
                    返回 未定!;
                }
                返回 result;
            }

            函数 computeBaseConstraint(t: 类型_): 类型_ {
                如果 (t.标志 & 类型标志_.类型参数_) {
                    常量 constraint = getConstraintFromTypeParameter(<类型参数_>t);
                    返回 (t 转为 类型参数_).isThisType || !constraint ?
                        constraint! :
                        getBaseConstraint(constraint)!;
                }
                如果 (t.标志 & (类型标志_.联合_| 类型标志_.交叉_)) {
                    常量 types = (<联合或交叉类型_>t).类型组;
                    常量 baseTypes: 类型_[] = [];
                    循环 (常量 类型 属于 types) {
                        常量 baseType = getBaseConstraint(类型);
                        如果 (baseType) {
                            baseTypes.压入(baseType);
                        }
                    }
                    返回 t.标志 & 类型标志_.联合_ && baseTypes.长度 === types.长度 ? getUnionType(baseTypes) :
                        t.标志 & 类型标志_.交叉_ && baseTypes.长度 ? getIntersectionType(baseTypes) :
                            未定!;
                }
                返回 t;
            }
        }

        函数 popTypeResolution(): 真假 {
            解析的目标组.弹出();
            解析的属性名称组.弹出();
            返回 !!解析的结果组.弹出();
        }

        函数 getConstraintFromTypeParameter(typeParameter: 类型参数_): 类型_ | 未定 {
            如果 (!typeParameter.约束) {
                如果 (typeParameter.目标) {
                    常量 targetConstraint = getConstraintOfTypeParameter(typeParameter.目标);
                    typeParameter.约束 = targetConstraint ? instantiateType(targetConstraint, typeParameter.映射) : 无约束类型;
                }
                否则 {
                    常量 constraintDeclaration = getConstraintDeclaration(typeParameter);
                    typeParameter.约束 = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : 无约束类型;
                }
            }
            返回 typeParameter.约束 === 无约束类型 ? 未定 : typeParameter.约束;
        }

        函数 getConstraintOfTypeParameter(typeParameter: 类型参数_): 类型_ | 未定 {
            返回 hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : 未定;
        }

        函数 instantiateTypes(types: 只读数组_<类型_>, mapper: 类型映射_): 只读数组_<类型_>;
        函数 instantiateTypes(types: 只读数组_<类型_> | 未定, mapper: 类型映射_): 只读数组_<类型_> | 未定;
        函数 instantiateTypes(types: 只读数组_<类型_> | 未定, mapper: 类型映射_): 只读数组_<类型_> | 未定 {
            返回 instantiateList<类型_>(types, mapper, instantiateType);
        }

        函数 instantiateList<T>(items: 只读数组_<T>, mapper: 类型映射_, instantiator: (item: T, mapper: 类型映射_) => T): 只读数组_<T>;
        函数 instantiateList<T>(items: 只读数组_<T> | 未定, mapper: 类型映射_, instantiator: (item: T, mapper: 类型映射_) => T): 只读数组_<T> | 未定;
        函数 instantiateList<T>(items: 只读数组_<T> | 未定, mapper: 类型映射_, instantiator: (item: T, mapper: 类型映射_) => T): 只读数组_<T> | 未定 {
            如果 (items && items.长度) {
                循环 (变量 i = 0; i < items.长度; i++) {
                    常量 item = items[i];
                    常量 mapped = instantiator(item, mapper);
                    如果 (item !== mapped) {
                        常量 result = i === 0 ? [] : items.分切(0, i);
                        result.压入(mapped);
                        循环 (i++; i < items.长度; i++) {
                            result.压入(instantiator(items[i], mapper));
                        }
                        返回 result;
                    }
                }
            }
            返回 items;
        }

        函数 instantiateType(类型: 类型_, mapper: 类型映射_ | 未定): 类型_;
        函数 instantiateType(类型: 类型_ | 未定, mapper: 类型映射_ | 未定): 类型_ | 未定;
        函数 instantiateType(类型: 类型_ | 未定, mapper: 类型映射_ | 未定): 类型_ | 未定 {
            如果 (!类型 || !mapper || mapper === identityMapper) {
                返回 类型;
            }
            如果 (instantiationDepth === 50) {
                // We have reached 50 recursive 类型 instantiations and there is a very high likelyhood we're dealing
                // with a combination of infinite generic types that perpetually generate new 类型 identities. We stop
                // the recursion here by yielding the error 类型.
                返回 未知类型;
            }
            instantiationDepth++;
            常量 result = instantiateTypeWorker(类型, mapper);
            instantiationDepth--;
            返回 result;
        }


        函数 instantiateTypeWorker(类型: 类型_, 映射: 类型映射_): 类型_ {
            如果 (是指针类型(类型)) {
                类型.基础类型 = instantiateType(类型.基础类型, 映射)
            }
            如果 (类型.标志 & 类型标志_.类型参数_) {
                返回 映射(<类型参数_>类型);
            }
            如果 (类型.标志 & 类型标志_.对象_) {
                如果 ((<对象类型_>类型).对象标志 & 对象标志_.匿名_) {
                    // If the anonymous 类型 originates in a declaration of a function, method, class, or
                    // interface, in an object 类型 literal, or in an object literal expression, we may need
                    // to instantiate the 类型 because it might reference a 类型 parameter.
                    返回 类型.符号 && 类型.符号.标志 & (符号标志_.函数_ | 符号标志_.方法_ | 符号标志_.结构字面量_) && 类型.符号.声明组 ?
                        getAnonymousTypeInstantiation(<匿名类型_>类型, 映射) : 类型;
                }
                如果 ((<对象类型_>类型).对象标志 & 对象标志_.引用_) {
                    常量 typeArguments = (<类型引用_>类型).类型实参;
                    常量 newTypeArguments = instantiateTypes(typeArguments!, 映射);
                    返回 newTypeArguments !== typeArguments ? createTypeReference((<类型引用_>类型).目标!, newTypeArguments 转为 []) : 类型;
                }
                返回 类型
            }
            如果 (类型.标志 & 类型标志_.联合_) {
                常量 类型组 = (<联合类型_>类型).类型组;
                常量 newTypes = instantiateTypes(类型组, 映射);
                返回 newTypes !== 类型组 ? getUnionType(newTypes 转为 [] , UnionReduction.Literal, 类型.aliasSymbol, instantiateTypes(类型.aliasTypeArguments!, 映射) 转为 []) : 类型;
            }
            如果 (类型.标志 & 类型标志_.交叉_) {
                常量 类型组 = (<交叉类型_>类型).类型组;
                常量 newTypes = instantiateTypes(类型组, 映射);
                返回 newTypes !== 类型组 ? getIntersectionType(newTypes 转为 [], 类型.aliasSymbol, instantiateTypes(类型.aliasTypeArguments!, 映射) 转为 []) : 类型;
            }
            返回 类型;
        }

        函数 createTypeReference(目标: 泛型类型_, typeArguments: 类型_[]): 类型引用_ {
            常量 id = getTypeListId(typeArguments);
            变量 类型 = 目标.instantiations.获取(id);
            如果 (!类型) {
                类型 = <类型引用_>创建对象类型(对象标志_.引用_, 目标.符号!);
                目标.instantiations.设置(id, 类型);
                类型.标志 |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0;
                类型.目标 = 目标;
                类型.类型实参 = typeArguments;
            }
            返回 类型;
        }

        函数 getOuterTypeParameters(node: 节点_): 类型参数_[] | 未定 {
            判断 (为真) {
                如果 (node.种类 === 语法_.方法声明_) {
                    常量 接受者 = (<方法声明_>node).接受者
                    变量 类型引用节点: 类型引用节点_ = 是指针类型节点(接受者.类型) ? <类型引用节点_>接受者.类型.基础类型 : <类型引用节点_>接受者.类型
                    变量 符号 = resolveTypeReferenceName(getTypeReferenceName(类型引用节点)!, 符号标志_.类型_);
                    常量 结构体声明 = <结构声明_>符号.声明组![0]
                    如果 (结构体声明.类型参数) {
                        变量 typeParameters: 类型参数_[] = []
                        循环 (变量 declaration 属于 结构体声明.类型参数) {
                            变量 tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration));
                            typeParameters = 附加如果唯一(typeParameters, tp);
                        }
                        返回 typeParameters;
                    }
                    返回 []
                }
                node = node.父节点; // TODO: GH#18217 Use SourceFile 种类 check instead
                如果 (!node) {
                    返回 未定;
                }
                假如 (node.种类) {
                    若是 语法_.结构声明_:
                    若是 语法_.类型别名声明_:
                    若是 语法_.类型声明_:
                        常量 outerTypeParameters = getOuterTypeParameters(node);
                        常量 outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters!, (<声明包括类型参数_>node).类型参数 || 空数组);
                        返回 outerAndOwnTypeParameters;
                    若是 语法_.方法声明_:
                        常量 接受者 = (<方法声明_>node).接受者
                        变量 类型引用节点: 类型引用节点_ = 是指针类型节点(接受者.类型) ? <类型引用节点_>接受者.类型.基础类型 : <类型引用节点_>接受者.类型
                        变量 符号 = resolveTypeReferenceName(getTypeReferenceName(类型引用节点)!, 符号标志_.类型_);
                        常量 结构体声明 = <结构声明_>符号.声明组![0]
                        返回 appendTypeParameters(outerTypeParameters!, 结构体声明.类型参数!)
                }
            }
        }

        函数 getAnonymousTypeInstantiation(类型: 匿名类型_, 映射: 类型映射_) {
            常量 target = 类型.对象标志 & 对象标志_.匿名_ ? 类型.目标 || 类型 : 类型;
            常量 符号 = target.符号!;
            常量 links = getSymbolLinks(符号);
            变量 typeParameters = links.outerTypeParameters
            如果 (!typeParameters) {
                // The first time an anonymous 类型 is instantiated we compute and store a list of the 类型
                // parameters that are in scope (and therefore potentially referenced). For 类型 literals that
                // aren't the right hand side of a generic 类型 alias declaration we optimize by reducing the
                // set of 类型 parameters to those that are possibly referenced in the literal.
                常量 declaration = 符号.声明组![0];
                变量 outerTypeParameters = getOuterTypeParameters(declaration);
                typeParameters = outerTypeParameters || 空数组;
                links.outerTypeParameters = typeParameters;
                如果 (typeParameters!.长度) {
                    links.instantiations = 创建词典<类型_>();
                    links.instantiations.设置(getTypeListId(typeParameters), target);
                }
            }
            如果 (typeParameters!.长度) {
                // We are instantiating an anonymous 类型 that has one or more 类型 parameters in scope. Apply the
                // 映射 to the 类型 parameters to produce the effective list of 类型 arguments, and compute the
                // instantiation cache key from the 类型 IDs of the 类型 arguments.
                常量 combinedMapper = 类型.对象标志 & 对象标志_.匿名_ ? combineTypeMappers(类型.映射!, 映射) : 映射;
                常量 typeArguments = 词典(typeParameters!, combinedMapper);
                常量 id = getTypeListId(typeArguments);
                变量 result = links.instantiations!.获取(id);
                如果 (!result) {
                    常量 newMapper = createTypeMapper(typeParameters!, typeArguments);
                    result = instantiateAnonymousType(target, newMapper);
                    links.instantiations!.设置(id, result);
                }
                返回 result;
            }
            返回 类型;
        }
        
        函数 instantiateAnonymousType(类型: 匿名类型_, 映射: 类型映射_): 匿名类型_ {
            常量 result = <匿名类型_>创建对象类型(类型.对象标志 | 对象标志_.匿名_, 类型.符号!);
            result.目标 = 类型;
            result.映射 = 映射;
            result.aliasSymbol = 类型.aliasSymbol;
            result.aliasTypeArguments = instantiateTypes(类型.aliasTypeArguments!, 映射) 转为 [];
            返回 result;
        }

        函数 combineTypeMappers(mapper1: 类型映射_, mapper2: 类型映射_): 类型映射_ {
            如果 (!mapper1) 返回 mapper2;
            如果 (!mapper2) 返回 mapper1;
            返回 t => instantiateType(mapper1(t), mapper2);
        }

        函数 makeUnaryTypeMapper(source: 类型_, 目标: 类型_) {
            返回 (t: 类型_) => t === source ? 目标 : t;
        }

        函数 makeBinaryTypeMapper(source1: 类型_, target1: 类型_, source2: 类型_, target2: 类型_) {
            返回 (t: 类型_) => t === source1 ? target1 : t === source2 ? target2 : t;
        }

        函数 makeArrayTypeMapper(sources: 只读数组_<类型_>, targets: 只读数组_<类型_>) {
            返回 (t: 类型_) => {
                循环 (变量 i = 0; i < sources.长度; i++) {
                    如果 (t === sources[i]) {
                        返回 targets ? targets[i] : 通用类型;
                    }
                }
                返回 t;
            };
        }

        函数 createTypeMapper(sources: 只读数组_<类型参数_>, targets: 只读数组_<类型_>): 类型映射_ {
            调试_.断言(targets === 未定 || sources.长度 === targets.长度);

            返回 sources.长度 === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : 通用类型) :
                sources.长度 === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : 通用类型, sources[1], targets ? targets[1] : 通用类型) :
                    makeArrayTypeMapper(sources, targets);
        }

        函数 getConstraintDeclaration(类型: 类型参数_) {
            返回 类型.符号 && 获取类型参数声明(类型.符号)!.约束;
        }

        函数 获取类型参数声明(符号: 符号_): 类型参数声明_ | 未定 {
            变量 声明组 = 符号.声明组
            如果 (声明组) {
                循环 (常量 d 属于 声明组) {
                    如果 (d.种类 === 语法_.类型参数声明_) {
                        返回 d 转为 类型参数声明_;
                    }
                }
            }
            返回 未定
        }

        函数 getDeclaredTypeOfTypeParameter(符号: 符号_): 类型参数_ {
            常量 links = getSymbolLinks(符号);
            如果 (!links.declaredType) {
                常量 类型 = <类型参数_>创建类型(类型标志_.类型参数_);
                类型.符号 = 符号;
                links.declaredType = 类型;
            }
            返回 <类型参数_>links.declaredType;
        }

        函数 checkTypeParameter(n: 类型参数声明_) {
            如果 (n.表达式) {
                grammarErrorOnFirstToken(n.表达式, 诊断信息_.类型异常);
            }
            checkSourceElement(n.约束);
            checkSourceElement(n.默认);

            常量 typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(n));
            如果 (!hasNonCircularBaseConstraint(typeParameter)) {
                error(n.约束, 诊断信息_.Type_parameter_0_has_a_circular_constraint, `typeToString(typeParameter)`);
            }
            如果 (!hasNonCircularTypeParameterDefault(typeParameter)) {
                error(n.默认, 诊断信息_.Type_parameter_0_has_a_circular_default, `typeToString(typeParameter)`);
            }
            常量 constraintType = getConstraintOfTypeParameter(typeParameter);
            常量 defaultType = getDefaultFromTypeParameter(typeParameter);
            如果 (constraintType && defaultType) {
                checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), n.默认, 诊断信息_.Type_0_does_not_satisfy_the_constraint_1);
            }
        }

        函数 getDefaultFromTypeParameter(typeParameter: 类型参数_): 类型_ | 未定 {
            常量 defaultType = getResolvedTypeParameterDefault(typeParameter);
            返回 defaultType !== 无约束类型 && defaultType !== 循环自身约束类型 ? defaultType : 未定;
        }

        函数 getResolvedTypeParameterDefault(typeParameter: 类型参数_): 类型_ | 未定 {
            如果 (!typeParameter.默认) {
                如果 (typeParameter.目标) {
                    常量 targetDefault = getResolvedTypeParameterDefault(typeParameter.目标);
                    typeParameter.默认 = targetDefault ? instantiateType(targetDefault, typeParameter.映射) : 无约束类型;
                }
                否则 {
                    // To block recursion, set the initial value to the resolvingDefaultType.
                    typeParameter.默认 = 解析中默认类型;
                    常量 defaultDeclaration = typeParameter.符号 && 循环执行(typeParameter.符号.声明组!, decl => isTypeParameterDeclaration(decl) && decl.默认);
                    常量 defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : 无约束类型;
                    如果 (typeParameter.默认 === 解析中默认类型) {
                        // If we have not been called recursively, set the correct default 类型.
                        typeParameter.默认 = defaultType;
                    }
                }
            }
            否则 如果 (typeParameter.默认 === 解析中默认类型) {
                // If we are called recursively for this 类型 parameter, mark the default as circular.
                typeParameter.默认 = 循环自身约束类型;
            }
            返回 typeParameter.默认;
        }

        函数 检查参数声明(n: 参数声明_) {
            checkSourceElement(n.类型)
            变量 参数类型 = getTypeOfParameter(n.符号)
            参数类型
        }

        函数 checkPropertyDeclaration(n: 属性声明_) {
            变量 符号 = getSymbolOfNode(n)
            变量 链接 = getSymbolLinks(符号)
            如果 (!链接.类型) {
                链接.类型 = getTypeFromTypeNode(n.类型)
            }
        }

        函数 checkSignatureDeclaration(n: 签名声明_) {
            检查类型参数(n.类型参数)
            如果 (n.参数 && n.参数.长度) {
                填充声明类型注释(n.参数)
                循环执行(n.参数, checkSourceElement)
            }
            如果 (n.类型) checkSourceElement(n.类型)
        }

        函数 检查方法接受者(n: 接受者声明_) {
            变量 符号 = getSymbolOfNode(n)
            getTypeOfSymbol(符号)
        }

        函数 checkMethodDeclaration(n: 方法签名_ | 方法声明_) {
            检查类型参数(n.类型参数)
            如果 (是方法声明(n)) {
                检查方法接受者(n.接受者)
            }
            如果 (n.参数 && n.参数.长度) {
                填充声明类型注释(n.参数)
                循环执行(n.参数, checkSourceElement)
            }
            如果 (n.类型) checkSourceElement(n.类型)
            如果 (是方法声明(n)) {
                checkSourceElement(n.主体!)
            }
        }

        函数 checkTypeReferenceNode(node: 类型引用节点_ | 表达式包括类型参数_) {
            checkGrammarTypeArguments(node, node.类型实参!);
            常量 类型 = getTypeFromTypeReference(node);
            如果 (类型 !== 未知类型) {
                如果 (node.类型实参) {
                    // Do 类型 argument local checks only 如果 referenced 类型 is successfully resolved
                    循环执行(node.类型实参, checkSourceElement);
                    常量 typeParameters = getTypeParametersForTypeReference(node);
                    如果 (typeParameters) {
                        checkTypeArgumentConstraints(node, typeParameters);
                    }
                }
            }
        }


        函数 getTypeParametersForTypeReference(node: 类型引用节点_ | 表达式包括类型参数_) {
            常量 类型 = getTypeFromTypeReference(node);
            如果 (类型 !== 未知类型) {
                常量 符号 = getNodeLinks(node).解析的符号;
                如果 (符号) {
                    返回 符号.标志 & 符号标志_.类型别名_ && getSymbolLinks(符号).类型参数 || 符号.标志 & 符号标志_.类型声明_ && getSymbolLinks(符号).类型参数 ||
                        符号.标志 & 符号标志_.结构_ && getSymbolLinks(符号).类型参数 || 符号.标志 & 符号标志_.接口_ && getSymbolLinks(符号).类型参数;
                }
            }
            返回 未定;
        }

        函数 checkTypeArgumentConstraints(node: 类型引用节点_ | 表达式包括类型参数_, typeParameters: 只读数组_<类型参数_>): 真假 {
            变量 typeArguments!: 类型_[];
            变量 映射!: 类型映射_;
            变量 result = 为真;
            循环 (变量 i = 0; i < typeParameters.长度; i++) {
                常量 constraint = getConstraintOfTypeParameter(typeParameters[i]);
                如果 (constraint) {
                    如果 (!typeArguments) {
                        typeArguments = getEffectiveTypeArguments(node, typeParameters);
                        映射 = createTypeMapper(typeParameters, typeArguments);
                    }
                    result = result && checkTypeAssignableTo(
                        typeArguments[i],
                        instantiateType(constraint, 映射),
                        node.类型实参![i],
                        诊断信息_.Type_0_does_not_satisfy_the_constraint_1);
                }
            }
            返回 result;
        }

        函数 getEffectiveTypeArguments(node: 类型引用节点_ | 表达式包括类型参数_, typeParameters: 只读数组_<类型参数_>) {
            返回 fillMissingTypeArguments(词典(node.类型实参!, getTypeFromTypeNode), typeParameters,
                getMinTypeArgumentCount(typeParameters));
        }

        函数 checkArrayType(n: 数组类型节点_) {
            checkSourceElement(n.元素类型)
            如果 (n.长度) {
                checkSourceElement(n.长度)
            }
        }

        函数 检查列表类型(n: 列表类型节点_) {
            checkSourceElement(n.元素类型)
        }

        函数 检查词典类型(n: 词典类型节点_) {
            checkSourceElement(n.键类型)
            checkSourceElement(n.值类型)
        }

        函数 检查通信类型(n: 通信类型节点_ | 只读通信节点_ | 只写通信节点_) {
            checkSourceElement(n.元素类型)
        }

        函数 checkUnionOrIntersectionType(n: 联合类型节点_ | 交叉类型节点_) {
            循环执行(n.类型组, checkSourceElement);
        }

        函数 checkJSDocTag(n: JSDoc标签_) {
            n
        }

        函数 checkFunctionDeclaration(n: 函数声明_) {
            检查类型参数(n.类型参数)
            如果 (n.参数 && n.参数.长度) {
                填充声明类型注释(n.参数)
                循环执行(n.参数, checkSourceElement)
            }
            如果 (n.类型) {
                checkSourceElement(n.类型)
            }
            如果 (n.主体) {
                checkSourceElement(n.主体)
            }
            registerForUnusedIdentifiersCheck(n);
        }

        函数 检查函数签名声明(n: 函数签名_) {
            检查类型参数(n.类型参数)
            如果 (n.参数 && n.参数.长度) {
                填充声明类型注释(n.参数)
                循环执行(n.参数, checkSourceElement)
            }
            如果 (n.类型) {
                checkSourceElement(n.类型)
            }
        }

        函数 检查类型参数(n: 节点数组_<类型参数声明_> | 未定) {
            如果 (n) {
                循环执行(n, checkSourceElement)
            }
        }

        函数 检查启动或初始函数声明(n: 启动函数声明_ | 初始函数声明_) {
            checkSourceElement(n.主体!)
        }

        函数 checkBlock(n: 块_) {
            循环执行(n.语句组, checkSourceElement)
        }

        函数 填充声明类型注释(ns: 只读数组_<变量声明_ | 参数声明_ | 属性声明_>) {
            如果 (ns && ns.长度) {
                变量 收集前方无类型声明: (变量声明_ | 参数声明_ | 属性声明_)[] = []
                常量 变长参数应该的索引 = ns.长度 - 1
                循环 (变量 i = 0; i < ns.长度; i++) {
                    变量 d = ns[i]
                    如果 (!d.类型) {
                        收集前方无类型声明.压入(d)
                    }
                    否则 如果 (是变长参数类型节点(d.类型!)) {
                        如果 (变长参数应该的索引 !== i) {
                            error(d, 诊断信息_.可变参数_0_不是最后一个参数, '可变参数')
                        }
                        如果 (收集前方无类型声明.长度) {
                            收集前方无类型声明.循环执行(d => {
                                error(d, 诊断信息_.声明_0_需要指定_类型节点, '参数声明')
                            })
                        }
                    }
                    否则 如果 (是简洁变量语句(d)) {
                        error(d, 诊断信息_.简洁变量声明不需要指定类型_变量的类型是从初始化表达式推断出来的)
                        // 简洁变量的类型节点不进行传播
                    }
                    否则 如果 (收集前方无类型声明.长度) {
                        循环执行(收集前方无类型声明, 无类型声明 => 无类型声明.类型 = d.类型)
                        收集前方无类型声明 = []
                    }
                }

                如果 (收集前方无类型声明.长度) {
                    收集前方无类型声明.循环执行(d => {
                        如果 (是属性声明(d)) {
                            error(d, 诊断信息_.声明_0_需要指定_类型节点, '属性声明')
                        }
                        否则 如果 (是参数声明(d)) {
                            变量 父节点 = d.父节点
                            如果 (!(父节点 && 是函数表达式或箭头函数(父节点) && 父节点.父节点 && 是调用表达式(父节点.父节点))) {
                                error(d, 诊断信息_.声明_0_需要指定_类型节点, '参数声明')
                            }
                        }
                        如果 (是变量声明(d) && (!d.父节点 || !(<变量语句_>d.父节点).初始化组)) {
                            error(d, 诊断信息_.声明_0_需要指定_类型节点_或_初始化表达式, '变量声明')
                        }
                    })
                }
            }
        }

        函数 检查枚举声明语句(n: 枚举声明_) {
            循环 (变量 i = 0; i < n.成员.长度; i++) {
                常量 md = n.成员[i]
                如果 (i === 0 && !md.初始化) {
                    md.初始化 = 创建自增常量表达式()!
                }
                设置常量链接(md)
                常量 nmd = n.成员[i + 1]
                如果 (!nmd) 返回
                如果 (nmd.初始化) 继续
                nmd.初始化 = 创建自增常量表达式(md.初始化!)
            }
        }

        函数 检查常量列表语句(n: 常量列表语句_) {
            循环 (变量 i = 0; i < n.声明组.长度; i++) {
                常量 d = n.声明组[i]
                如果 (!d.初始化 && i === 0) {
                    返回  // 错误
                }
                设置常量链接(d)
                常量 nd = n.声明组[i + 1]
                如果 (!nd) 返回
                如果 (nd.初始化) 继续
                nd.初始化 = 创建自增常量表达式(d.初始化!)
            }
        }

        函数 设置常量链接(d: 常量列表元素_ | 枚举成员声明_) {
            变量 链接 = getSymbolLinks(d.符号)
            如果 (!链接.常量或枚举常量值 && d.初始化) {
                常量 常量值 = 计算常量值(d.初始化!)
                如果 (常量值) {
                    链接.常量或枚举常量值 = 常量值
                    链接.declaredType = checkExpression(d.初始化!)
                }
            }
        }

        函数 计算常量值(n: 表达式_): 数字 | 文字 | 未定 {
            如果 (!n) {
                返回 未定
            }
            假如 (n.种类) {
                若是 语法_.前缀一元表达式_:
                    常量 值 = 计算常量值((<前缀一元表达式_>n).算子)
                    如果 (类为 值 === "数字") {
                        假如 ((<前缀一元表达式_>n).运算符) {
                            若是 语法_.加号_: 返回 +值
                            若是 语法_.减号_: 返回 -值
                            若是 语法_.波折号_: 返回 ~值
                        }
                    }
                    跳出
                若是 语法_.二元表达式_:
                    常量 左侧 = 计算常量值((<二元表达式_>n).左侧);
                    常量 右侧 = 计算常量值((<二元表达式_>n).右侧);
                    如果 (类为 左侧 === "数字" && 类为 右侧 === "数字") {
                        假如 ((<二元表达式_>n).运算符令牌.种类) {
                            若是 语法_.或号_: 返回 左侧 | 右侧;
                            若是 语法_.且号_: 返回 左侧 & 右侧;
                            若是 语法_.双右尖号_: 返回 左侧 >> 右侧;
                            若是 语法_.双左尖号_: 返回 左侧 << 右侧;
                            若是 语法_.异或号_: 返回 左侧 ^ 右侧;
                            若是 语法_.星号_: 返回 左侧 * 右侧;
                            若是 语法_.斜杠号_: 返回 左侧 / 右侧;
                            若是 语法_.加号_: 返回 左侧 + 右侧;
                            若是 语法_.减号_: 返回 左侧 - 右侧;
                            若是 语法_.百分号_: 返回 左侧 % 右侧;
                        }
                    }
                    如果 (类为 左侧 === "文字" && 类为 右侧 === "文字") {
                        如果 ((<二元表达式_>n).运算符令牌.种类 === 语法_.加号_) 返回 左侧 + 右侧;
                    }
                    跳出
                若是 语法_.文本字面量_:
                    返回 (<文本字面量_>n).文本
                若是 语法_.数字字面量_:
                    返回 +(<数字字面量_>n).文本
                若是 语法_.字符字面量_:
                    返回 (<字符字面量_>n).文本.字符代码在(0)
                若是 语法_.括号表达式_:
                    返回 计算常量值((<括号表达式_>n).表达式)
                若是 语法_.标识符_:
                    变量 符号 = getResolvedSymbol(<标识符_>n)
                    如果 (符号 && 符号.标志 & 符号标志_.别名_) {
                        符号 = resolveAlias(符号)
                    }
                    如果 (符号 && 符号.标志 & 符号标志_.常量_) {
                        常量 链接 = getSymbolLinks(符号)
                        返回 链接.常量或枚举常量值
                    }
                    // 错误
                    返回 0
                若是 语法_.属性访问表达式_:
                若是 语法_.限定名_: {
                    变量 左侧: 表达式_ | 实体名称_
                    变量 右侧: 标识符_
                    如果 (是属性访问表达式(n)) {
                        左侧 = n.表达式
                        右侧 = n.名称
                    }
                    否则 如果 (是限定名(n)) {
                        左侧 = n.左侧
                        右侧 = n.右侧
                    }
                    变量 左侧类型 = checkExpression(左侧!)
                    变量 属性符号 = getPropertyOfType(左侧类型, 右侧!.文本)
                    如果 (属性符号 && 属性符号.标志 & 符号标志_.常量_) {
                        常量 链接 = getSymbolLinks(属性符号)
                        返回 链接.常量或枚举常量值
                    }
                }
            }
            error(n, 诊断信息_.常量声明_0_的值不能计算, '常量表达式')
            返回 未定
        }

        函数 创建自增常量表达式(n?: 表达式_) {
            如果 (!n) {
                常量 表达式 = <数字字面量_>创建节点(语法_.数字字面量_, -1, -1)
                表达式.文本 = '0'
                返回 表达式
            }
            假如 (n.种类) {
                若是 语法_.数字字面量_: {
                    常量 表达式 = <数字字面量_>创建节点(语法_.数字字面量_, -1, -1)
                    表达式.文本 = '' + (+(<数字字面量_>n).文本 + 1)
                    返回 表达式
                }
                若是 语法_.二元表达式_:
                    变量 运算符 = (<二元表达式_>n).运算符令牌
                    假如 (运算符.种类) {
                        若是 语法_.加号_:
                        若是 语法_.减号_:
                        若是 语法_.星号_:
                        若是 语法_.斜杠号_:
                        若是 语法_.百分号_:
                        若是 语法_.且号_:
                        若是 语法_.或号_:
                        若是 语法_.异或号_:
                        若是 语法_.双左尖号_:
                        若是 语法_.双右尖号_:
                            常量 右侧值 = 计算常量值((<二元表达式_>n).右侧)
                            如果 (右侧值 && 类为 右侧值 === "数字") {
                                常量 二元表达式 = <二元表达式_>创建节点(语法_.二元表达式_, -1, -1)
                                二元表达式.运算符令牌 = 运算符
                                二元表达式.左侧 = (<二元表达式_>n).左侧
                                常量 右侧 = <数字字面量_>创建节点(语法_.数字字面量_, -1, -1)
                                右侧.文本 = '' + (1 + 右侧值)
                                二元表达式.右侧 = 右侧
                                返回 二元表达式
                            }
                    }
                默认:
                    error(n, 诊断信息_.常量声明_0_的值不能计算, '常量表达式')
                    返回
            }
        }

        函数 检查常量语句(n: 常量语句_) {
            如果 (分配初始化表达式(n)) {
                循环执行(n.声明组, checkSourceElement)
            }
        }

        函数 检查常量声明(n: 常量声明_) {
            变量 链接 = getSymbolLinks(n.符号)
            如果 (!链接.常量或枚举常量值 && n.初始化) {
                变量 常量值 = 计算常量值(n.初始化!)
                如果 (常量值) {
                    链接.常量或枚举常量值 = 常量值
                    链接.declaredType = checkExpression(n.初始化!)
                }
            }
        }

        函数 分配初始化表达式(n: 常量语句_) {
            如果 (n.声明组.长度 <= n.初始化组.长度) {
                循环 (变量 i = 0; i < n.声明组.长度; i++) {
                    常量 d = n.声明组[i]
                    d.初始化 = n.初始化组[i]
                }
                如果 (n.声明组.长度 !== n.初始化组.长度) {
                    error(n, 诊断信息_.常量声明与初始化表达式数量不匹配)
                }
                返回 为真
            }
            // 错误
            返回 为假
        }

        函数 checkVariableStatement(n: 变量语句_ | 简洁变量语句_) {
            填充声明类型注释(n.声明组)
            解析变量声明表达式(n)
        }

        /*
        函数 是结构类型(t: 类型_): t 作为 结构类型_ {
            如果 (!!(t.标志 & 类型标志_.结构_)) {
                返回 !!((<对象类型_>t).对象标志 & 对象标志_.结构_)
            }
            返回 为假
        }
        */

        函数 是接口结构类型(t: 类型_): t 作为 结构类型_ {
            如果 (!!(t.标志 & 类型标志_.对象_)) {
                返回 !!((<对象类型_>t).对象标志 & 对象标志_.接口_)
            }
            返回 为假
        }

        函数 是返回值结构类型(t: 类型_): t 作为 返回值类型_ {
            如果 (!!(t.标志 & 类型标志_.对象_)) {
                返回 !!((<对象类型_>t).对象标志 & 对象标志_.返回值_)
            }
            返回 为假

        }

        /*
        函数 是指针类型(t: 类型_): 真假{
            返回 !!(t.标志 & 类型标志_.指针类型_)
        }
        */

        /**
         * 初始化表达式的数量(展开多返回类型后)的总数必须与声明的数量相等
         * 例如:
         *   1  2   3   4  ===   1                      2  3                       3  4
         *   |  |   |   |        |                       \/                         \/   
         *   a, b, err, c, _ := 100, / 2个返回值的函数 / f(100), / 2个返回值的函数 / ff(100), 
         *                 |
         *          空标识符只是站位作用
         */
        函数 解析变量声明表达式(n: 变量语句_ | 简洁变量语句_) {
            如果 (n.初始化组 && n.初始化组.长度) {
                变量 索引 = 0;
                判断 (索引 < n.初始化组.长度) {
                    常量 初始化表达式 = n.初始化组![索引]
                    变量 初始化类型 = getTypeOfExpression(初始化表达式)
                    如果 (是返回值结构类型(初始化类型)) {
                        常量 解析的类型 = resolveStructuredTypeMembers(<对象类型_>初始化类型)
                        如果 (解析的类型.属性组.长度) {
                            循环 (变量 i = 0; i < 解析的类型.属性组.长度; i++) {
                                变量 对应声明 = n.声明组[索引]
                                变量 对应的类型属性 = 解析的类型.属性组[i]
                                如果 (!对应声明) {
                                    error(n, 诊断信息_.没为初始化表达式_0_声明足够的变量, '初始化表达式')
                                    返回
                                }
                                如果 (开始包含(对应的类型属性.名称, '@')) {
                                    getSymbolLinks(对应声明.符号).类型 = getTypeFromTypeNode((<类型节点_>对应的类型属性.值声明))
                                }
                                否则 {
                                    getSymbolLinks(对应声明.符号).类型 = getTypeOfSymbol(对应的类型属性)
                                }
                                索引++
                            }
                        }
                        否则 {
                            getSymbolLinks(n.声明组[索引].符号).类型 = 解析的类型
                            索引++
                        }
                    }
                    否则 {
                        变量 对应声明 = n.声明组[索引]
                        如果 (!对应声明) {
                            error(n, 诊断信息_.没为初始化表达式_0_声明足够的变量, '初始化表达式')
                            返回
                        }
                        如果 (!(对应声明.修饰符标志缓存! & 修饰符组_.是空标识符_)) {
                            如果 (对应声明.类型) {
                                变量 注释类型 = getTypeFromTypeNode(对应声明.类型)
                                // 检测 注释类型 与初始化类型是否为 可赋值关系
                                // 不推荐 初始化表达式和 类型注释 同时存在
                                注释类型
                                初始化类型
                            }
                            getSymbolLinks(对应声明.符号).类型 = 初始化类型
                        }
                        索引++
                    }
                }
            }
            否则 如果 (n.声明组) {
                循环执行(n.声明组, checkSourceElement)
            }
        }

        函数 checkExpressionStatement(n: 表达式语句_) {
            checkExpression(n.表达式);
        }

        函数 checkIfStatement(n: 如果语句_ | 另如语句_) {
            checkExpression(n.表达式)
            checkSourceElement(n.然后语句)
            checkSourceElement(n.另如语句!)
            checkSourceElement(n.否则语句!)
        }

        函数 checkForStatement(n: 循环语句_) {
            checkSourceElement(n.初始化)
            如果 (n.条件) checkExpression(n.条件)
            循环执行(n.增量器, checkSourceElement)
            checkSourceElement(n.迭代体)
        }

        函数 跳过外观类型(t: 类型_): 类型_ {
            如果 (是指针类型(t)) {
                如果 (是数组类型(t.基础类型)) {
                    返回 t.基础类型
                }
                否则 如果 (是类型声明类型(t.基础类型)) {
                    返回 跳过外观类型(t.基础类型)
                }
            }
            如果 (是类型声明类型(t)) {
                返回 跳过外观类型(t.基础类型!)
            }
            返回 t
        }

        /*
        函数 是类型引用(t: 类型_): t 作为 类型引用_{
           返回 !!(t.标志& 类型标志_.对象_ &&  (<对象类型_>t).对象标志 & 对象标志_.引用_)
        }
        */

        函数 checkForOfStatement(n: 循环属于语句_) {
            如果 (!n.声明组) {
                error(n, 诊断信息_.没有可遍历的声明)
            }
            循环执行(n.声明组, checkSourceElement)
            变量 表达式类型 = checkExpression(n.表达式)
            表达式类型 = 跳过外观类型(表达式类型)
            变量 变量1链接: SymbolLinks | 未定
            变量 变量2链接: SymbolLinks | 未定
            如果 (长度(n.声明组) === 2) {
                变量1链接 = getSymbolLinks(getSymbolOfNode(n.声明组[0]))
                变量2链接 = getSymbolLinks(getSymbolOfNode(n.声明组[1]))
            }
            否则 如果 (长度(n.声明组) === 1) {
                变量1链接 = getSymbolLinks(getSymbolOfNode(n.声明组[0]))
            }
            否则 如果 (长度(n.声明组) > 2) {
                循环 (变量 i = 2; i < n.声明组.长度; i++) {
                    error(n.声明组[i]!, 诊断信息_.循环变量_0_没有对应初始值)
                }
            }
            如果 (是文本类型(表达式类型)) {
                如果 (变量1链接) 变量1链接.类型 = 整数类型
                如果 (变量2链接) 变量2链接.类型 = 字符类型
            }
            否则 如果 (是列表类型(表达式类型) || 是数组类型(表达式类型)) {
                如果 (变量1链接) 变量1链接.类型 = 整数类型
                如果 (变量2链接) 变量2链接.类型 = 表达式类型.基础类型
            }
            否则 如果 (是词典类型(表达式类型)) {
                如果 (变量1链接) 变量1链接.类型 = 表达式类型.键类型
                如果 (变量2链接) 变量2链接.类型 = 表达式类型.值类型
            }
            否则 如果 (是通信类型(表达式类型) || 是只读通信类型(表达式类型)) {
                如果 (变量1链接) 变量1链接.类型 = 表达式类型.基础类型
                如果 (变量2链接) error(n.声明组[1], 诊断信息_.循环变量_0_没有对应初始值)
            }
            否则 {
                error(n.表达式, 诊断信息_.不是_属于循环_支持的类型)
            }
            checkSourceElement(n.迭代体)
        }

        函数 检查删除或执行语句(n: 删除语句_ | 执行语句_ | 善后语句_) {
            checkExpression(n.表达式)
        }

        函数 checkBreakOrContinueStatement(n: 跳出或继续语句_) {
            n
        }

        函数 检查返回语句(n: 返回语句_) {
            n
        }

        函数 checkSwitchStatement(n: 假如语句_) {
            n
        }

        函数 checkLabeledStatement(n: 标签语句_) {
            查找祖先(n.父节点,
                上级标签 => {
                    如果 (是函数族(上级标签)) {
                        返回 "quit";
                    }
                    如果 (上级标签.种类 === 语法_.标签语句_ && (<标签语句_>上级标签).标签.文本 === n.标签.文本) {
                        grammarErrorOnNode(n.标签, 诊断信息_.重复的标签_0, `getTextOfNode(node.label)`);
                        返回 为真;
                    }
                });

            checkSourceElement(n.语句);
        }

        函数 获取类型引用节点全名(n: 实体名或实体名表达式_): 文字 {
            假如 (n.种类) {
                若是 语法_.标识符_:
                    返回 (<标识符_>n).文本
                若是 语法_.属性访问表达式_:
                    变量 表达式 = (<属性访问表达式_>n).表达式
                    如果 (是实体名称表达式(表达式)) {
                        变量 名称 = (<属性访问表达式_>n).名称.文本
                        返回 获取类型引用节点全名(表达式) + '.' + 名称
                    }
                若是 语法_.限定名_:
                    变量 左侧 = (<限定名_>n).左侧
                    变量 名称 = (<限定名_>n).右侧.文本
                    返回 获取类型引用节点全名(左侧) + '.' + 名称
            }
        }

        函数 检查接口声明(n: 接口声明_) {
            检查类型参数(n.类型参数)
            变量 错误过滤集合 = 创建词典<为真>()
            错误过滤集合.设置(n.名称.文本, 为真)
            变量 匿名成员 = 创建词典<类型引用节点_>()
            检查接口声明属性组(n, 错误过滤集合, 匿名成员, n)
            变量 链接 = getSymbolLinks(n.符号)
            如果 (!链接.declaredType) {
                如果 (n.成员) {
                    循环执行(n.成员, t => {
                        如果 (是类型引用节点(t)) {
                            变量 名称 = 获取类型引用节点全名(t.类型名)
                            如果 (!匿名成员.具有(名称)) {
                                匿名成员.设置(名称, t)
                            }
                        }
                    })
                }
                如果 (匿名成员.大小) {
                    匿名成员.循环执行(t => {
                        变量 类型 = getTypeFromTypeReference(t)
                        如果 (是接口结构类型(类型) && 类型 !== 通用类型) {
                            n.符号.成员 && 类型.符号!.成员 ? mergeSymbolTable(n.符号.成员!, 类型.符号!.成员) :
                                类型.符号!.成员 ? n.符号.成员 = 类型.符号!.成员 :
                                    未定
                        }
                        否则 {
                            error(t, 诊断信息_.接口成员中包含_通用类型)
                        }
                    })
                }
                链接.declaredType = getDeclaredTypeOfSymbol(n.符号)
            }
            变量 ln = getNodeLinks(n)
            如果 (!ln.完成接口成员合并) {
                ln.完成接口成员合并 = 为真
            }
        }

        函数 检查接口声明属性组(n: 接口声明_, 错误过滤集合: 词典_<为真>, 匿名成员: 词典_<类型引用节点_>, 错误节点: 接口声明_) {
            循环 (变量 i = 0; i < n.成员.长度; i++) {
                变量 ns = n.成员[i]
                如果 (是类型引用节点(ns)) {
                    变量 类型 = getTypeFromTypeReference(ns)
                    变量 引用符号 = 类型.符号!
                    变量 声明节点 = 引用符号.声明组![0]
                    如果 (是接口声明(声明节点)) {
                        变量 名称 = 获取类型引用节点全名(ns.类型名)
                        如果 (错误过滤集合!.具有(名称)) {
                            变量 错误符号 = 查找(错误节点.成员, tn => 是类型引用节点(tn) && 获取类型引用节点全名(tn.类型名) === 名称)
                            如果 (错误符号) {
                                匿名成员 = 未定!
                                error(错误符号, 诊断信息_.无效的匿名属性_可能有直接或间接递归引用错误)
                            }
                            返回
                        }
                        错误过滤集合!.设置(名称, 为真)
                        变量 ln = getNodeLinks(声明节点)
                        如果 (!ln.完成接口成员合并) {
                            匿名成员.设置(名称, ns)
                        }
                        检查接口声明属性组(<接口声明_>声明节点, 错误过滤集合, 匿名成员, 错误节点)
                    }
                    否则 {
                        匿名成员 = 未定!
                        error(ns, 诊断信息_.匿名接口成员只能是接口类型)
                    }
                }
                checkSourceElement(ns)
            }
        }

        函数 检查结构声明(n: 结构声明_) {
            检查类型参数(n.类型参数)
            变量 匿名缓存 = 创建词典<为真>()
            匿名缓存.设置(n.名称.文本, 为真)
            检查结构声明属性组(n, 匿名缓存, n)
        }

        函数 检查结构声明属性组(n: 结构声明_, 匿名缓存: 词典_<为真>, 错误节点: 结构声明_) {
            循环 (变量 i = 0; i < n.成员.长度; i++) {
                变量 ns = n.成员[i]
                循环 (变量 ii = 0; ii < ns.声明组.长度; ii++) {
                    变量 d = ns.声明组[ii]
                    如果 (!d.类型) {
                        填充声明类型注释(ns.声明组 转为 节点数组_<属性声明_>)
                    }
                    如果 (!是指针类型节点(d.类型) && 是类型引用节点(d.类型)) {
                        变量 引用符号 = resolveTypeReferenceName(d.类型.类型名, 符号标志_.类型_);
                        如果 (是结构声明(引用符号.声明组![0])) {
                            变量 名称 = 获取类型引用节点全名(d.类型.类型名)
                            如果 (匿名缓存!.具有(名称)) {
                                变量 错误符号 = 错误节点.符号.成员!.获取(名称)!
                                错误符号.声明组!.循环执行(d => {
                                    error(d, 诊断信息_.无效的匿名属性_可能有直接或间接递归引用错误)
                                })
                                返回
                            }
                            匿名缓存!.设置(名称, 为真)
                            检查结构声明属性组(<结构声明_>引用符号.声明组![0], 匿名缓存, 错误节点)
                        }
                    }
                    checkSourceElement(d)
                }
            }
        }

        函数 检查返回值声明属性组(ns: 返回值声明属性组_) {
            常量 最后的 = 最后或未定义(ns.声明组)
            如果 (最后的 && 是属性声明(最后的)) {
                填充声明类型注释(ns.声明组 转为 节点数组_<属性声明_>)
            }
            循环执行(ns.声明组, checkSourceElement)
        }

        函数 检查类型别名声明或类型声明(n: 类型别名声明_ | 类型声明_) {
            检查类型参数(n.类型参数)
            checkSourceElement(n.类型);
        }

        函数 检查导入声明(n: 导入声明_) {
            n
        }

        函数 检查导入从声明(n: 导入从声明_) {
            n
        }

        函数 检查程序集(n: 程序声明_) {
            循环执行(n.语句组, checkSourceElement)
        }

        函数 checkSourceElement(n: 节点_ | 未定): 无值 {
            如果 (!n) {
                返回;
            }
            假如 (n.种类) {
                若是 语法_.类型参数声明_:
                    返回 checkTypeParameter(<类型参数声明_>n);
                若是 语法_.参数_:
                    返回 检查参数声明(<参数声明_>n);
                若是 语法_.属性声明_:
                    返回 checkPropertyDeclaration(<属性声明_>n);
                若是 语法_.函数类型_:
                    返回 checkSignatureDeclaration(<函数类型节点_>n);
                若是 语法_.方法声明_:
                若是 语法_.方法签名_:
                    返回 checkMethodDeclaration(<方法签名_ | 方法声明_>n);
                若是 语法_.类型引用_:
                    返回 checkTypeReferenceNode(<类型引用节点_>n)
                若是 语法_.数组类型_:
                    返回 checkArrayType(<数组类型节点_>n);
                若是 语法_.列表类型_:
                    返回 检查列表类型(<列表类型节点_>n);
                若是 语法_.词典类型_:
                    返回 检查词典类型(<词典类型节点_>n);
                若是 语法_.通信类型_:
                若是 语法_.只读通信_:
                若是 语法_.只写通信_:
                    返回 检查通信类型(<通信类型节点_ | 只读通信节点_ | 只写通信节点_>n);
                若是 语法_.联合类型_:
                    返回 checkUnionOrIntersectionType(<联合类型节点_>n);
                若是 语法_.程序声明_:
                    返回 检查程序集((<程序声明_>n));
                若是 语法_.括号类型_:
                    返回 checkSourceElement((<括号类型节点_>n).类型);
                若是 语法_.JSDoc标签_:
                    返回 checkJSDocTag(<JSDoc标签_>n);
                若是 语法_.函数声明_:
                    返回 checkFunctionDeclaration(<函数声明_>n);
                若是 语法_.函数签名_:
                    返回 检查函数签名声明(<函数签名_>n);
                若是 语法_.创建函数签名_:
                    返回 检查函数签名声明(<函数签名_>n)
                若是 语法_.启动函数声明_:
                若是 语法_.初始函数声明_:
                    返回 检查启动或初始函数声明(<启动函数声明_ | 初始函数声明_>n);
                若是 语法_.块_:
                    返回 checkBlock(<块_>n);
                若是 语法_.常量声明_:
                    返回 检查常量声明(<常量声明_>n)
                若是 语法_.常量语句_:
                    返回 检查常量语句(<常量语句_>n)
                若是 语法_.常量列表语句_:
                    返回 检查常量列表语句(<常量列表语句_>n)
                若是 语法_.枚举声明_:
                    返回 检查枚举声明语句(<枚举声明_>n)
                若是 语法_.变量语句_:
                若是 语法_.简洁变量语句_:
                    返回 checkVariableStatement(<变量语句_ | 简洁变量语句_>n);
                若是 语法_.表达式语句_:
                    返回 checkExpressionStatement(<表达式语句_>n);
                若是 语法_.如果语句_:
                若是 语法_.另如语句_:
                    返回 checkIfStatement(<如果语句_>n);
                若是 语法_.循环语句_:
                    返回 checkForStatement(<循环语句_>n);
                若是 语法_.循环属于语句_:
                    返回 checkForOfStatement(<循环属于语句_>n);
                若是 语法_.删除语句_:
                若是 语法_.执行语句_:
                若是 语法_.善后语句_:
                    返回 检查删除或执行语句(<删除语句_ | 善后语句_ | 执行语句_>n)
                若是 语法_.继续语句_:
                若是 语法_.跳出语句_:
                    返回 checkBreakOrContinueStatement(<跳出或继续语句_>n);
                若是 语法_.返回语句_:
                    返回 检查返回语句(<返回语句_>n)
                若是 语法_.假如语句_:
                    返回 checkSwitchStatement(<假如语句_>n);
                若是 语法_.标签语句_:
                    返回 checkLabeledStatement(<标签语句_>n);
                若是 语法_.接口声明_:
                    返回 检查接口声明(<接口声明_>n);
                若是 语法_.返回值声明属性组_:
                    返回 检查返回值声明属性组(<返回值声明属性组_>n);
                若是 语法_.结构声明_:
                    返回 检查结构声明(<结构声明_>n);
                若是 语法_.枚举声明_:
                    返回 checkEnumDeclaration(<枚举声明_>n);
                若是 语法_.类型别名声明_:
                若是 语法_.类型声明_:
                    返回 检查类型别名声明或类型声明(<类型别名声明_ | 类型声明_>n);
                若是 语法_.导入声明_:
                    返回 检查导入声明(<导入声明_>n);
                若是 语法_.导入从声明_:
                    返回 检查导入从声明(<导入从声明_>n);
                若是 语法_.空语句_:
                    checkGrammarStatementInAmbientContext(n);
                    返回;
                若是 语法_.调试语句_:
                    checkGrammarStatementInAmbientContext(n);
                    返回;
            }
        }

        函数 checkSourceFile(n: 源文件_) {
            性能.标记("检查之前");
            checkSourceFileWorker(n);
            性能.标记("检查之后");
            性能.度量("检查", "检查之前", "检查之后");
        }

        函数 checkSourceFileWorker(n: 源文件_) {
            常量 links = getNodeLinks(n);
            如果 (!(links.标志! & NodeCheckFlags.TypeChecked)) {
                // Grammar checking
                checkGrammarSourceFile(n);
                clear(potentialNewTargetCollisions);

                循环执行(n.语句组, checkSourceElement);

                如果 (!n.是声明文件) {
                    checkUnusedIdentifiers();
                }
                links.标志! |= NodeCheckFlags.TypeChecked;
            }
        }

        函数 获取诊断组(sourceFile: 源文件_, ct: 取消令牌_): 诊断_[] {
            尝试 {
                // Record the cancellation token so it can be checked later on during checkSourceElement.
                // Do this in a finally block so we can ensure that it gets reset back to nothing after
                // this call is done.
                cancellationToken = ct;
                cancellationToken
                返回 getDiagnosticsWorker(sourceFile);
            }
            善后 {
                cancellationToken = 未定!;
            }
        }

        函数 getDiagnosticsWorker(sourceFile: 源文件_): 诊断_[] {
            throwIfNonDiagnosticsProducing();
            如果 (sourceFile) {
                diagnostics
                // Some global diagnostics are deferred until they are needed and
                // may not be reported in the firt call to getGlobalDiagnostics.
                // We should catch these changes and report them.
                常量 previousGlobalDiagnostics = diagnostics.获取全局诊断();
                常量 previousGlobalDiagnosticsSize = previousGlobalDiagnostics.长度;

                checkSourceFile(sourceFile);

                常量 semanticDiagnostics = diagnostics.获取诊断(sourceFile.文件名);
                常量 currentGlobalDiagnostics = diagnostics.获取全局诊断();
                如果 (currentGlobalDiagnostics !== previousGlobalDiagnostics) {
                    // If the arrays are not the same reference, new diagnostics were added.
                    常量 deferredGlobalDiagnostics = relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, 比较诊断);
                    返回 组合(deferredGlobalDiagnostics!, semanticDiagnostics);
                }
                否则 如果 (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.长度 > 0) {
                    // If the arrays are the same reference, but the length has changed, a single
                    // new diagnostic was added as DiagnosticCollection attempts to reuse the
                    // same array.
                    返回 组合(currentGlobalDiagnostics, semanticDiagnostics);
                }

                返回 semanticDiagnostics;
            }

            // Global diagnostics are always added when a file is not provided to
            // getDiagnostics
            循环执行(主机.获取源文件组(), checkSourceFile);
            返回 diagnostics.获取诊断();
        }

        函数 获取全局诊断(): 诊断_[] {
            throwIfNonDiagnosticsProducing();
            返回 diagnostics.获取全局诊断();
        }

        函数 throwIfNonDiagnosticsProducing() {
            如果 (!生产诊断) {
                抛出 新建 错误_("Trying to get diagnostics from a 类型 checker that does not produce them.");
            }
        }

        函数 checkGrammarSourceFile(node: 源文件_) {
            node
        }

        函数 hasParseDiagnostics(sourceFile: 源文件_): 真假 {
            返回 sourceFile.解析诊断信息.长度 > 0;
        }

        函数 grammarErrorOnFirstToken(node: 节点_, message: 诊断信息_, arg0?: 任意, arg1?: 任意, arg2?: 任意): 真假 | 未定 {
            常量 sourceFile = 获取节点的源文件(node);
            如果 (!hasParseDiagnostics(sourceFile)) {
                常量 span = 获取令牌在位置的跨度(sourceFile, node.首位);
                diagnostics.添加(创建文件诊断信息(sourceFile, span.开始, span.长度, message, arg0, arg1, arg2));
                返回 为真;
            }
        }

        函数 grammarErrorOnNode(node: 节点_, message: 诊断信息_, arg0?: 任意, arg1?: 任意, arg2?: 任意): 真假 | 未定 {
            常量 sourceFile = 获取节点的源文件(node);
            如果 (!hasParseDiagnostics(sourceFile)) {
                diagnostics.添加(创建诊断从节点(node, message, arg0, arg1, arg2));
                返回 为真;
            }
        }

        函数 checkGrammarStatementInAmbientContext(node: 节点_): 真假 | 未定 {
            如果 (node.标志 & 节点标志_.环境_) {

                // Find containing block which is either Block, ModuleBlock, 源文件_
                常量 links = getNodeLinks(node);
                如果 (!links.hasReportedStatementInAmbientContext && 是函数族(node.父节点)) {
                    返回 getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, 诊断信息_.An_implementation_cannot_be_declared_in_ambient_contexts);
                }

                // We are either parented by another statement, or some sort 属于 block.
                // If we're in a block, we only want to really report an error once
                // to prevent noisiness.  So use a bit on the block to indicate 如果
                // this has already been reported, and don't report 如果 it has.
                //
                如果 (node.父节点.种类 === 语法_.块_ || node.父节点.种类 === 语法_.源文件_) {
                    常量 links = getNodeLinks(node.父节点);
                    // Check 如果 the containing block ever report this error
                    如果 (!links.hasReportedStatementInAmbientContext) {
                        返回 links.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, 诊断信息_.Statements_are_not_allowed_in_ambient_contexts);
                    }
                }
                否则 {
                    // We must be parented by a statement.  If so, there's no need
                    // to report the error as our 父节点 will have already done it.
                    // Debug.assert(isStatement(node.父节点));
                }
            }
        }

        函数 checkGrammarTypeArguments(node: 节点_, typeArguments: 节点数组_<类型节点_>): 真假 {
            返回 checkGrammarForDisallowedTrailingComma(typeArguments) ||
                checkGrammarForAtLeastOneTypeArgument(node, typeArguments);
        }

        函数 checkGrammarForDisallowedTrailingComma(list: 节点数组_<节点_>): 真假 {
            如果 (list && list.有尾随逗号) {
                常量 start = list.尾位 - ",".长度;
                常量 end = list.尾位;
                返回 grammarErrorAtPos(list[0], start, end - start, 诊断信息_.Trailing_comma_not_allowed);
            }
            返回 为假
        }

        函数 checkGrammarForAtLeastOneTypeArgument(node: 节点_, typeArguments: 节点数组_<类型节点_>): 真假 {
            如果 (typeArguments && typeArguments.长度 === 0) {
                常量 sourceFile = 获取节点的源文件(node);
                常量 start = typeArguments.首位 - "<".长度;
                常量 end = 跳过杂项(sourceFile.文本, typeArguments.尾位) + ">".长度;
                返回 grammarErrorAtPos(sourceFile, start, end - start, 诊断信息_.Type_argument_list_cannot_be_empty);
            }
            返回 为假
        }

        函数 grammarErrorAtPos(nodeForSourceFile: 节点_, start: 数字, length: 数字, message: 诊断信息_, arg0?: 任意, arg1?: 任意, arg2?: 任意): 真假 {
            常量 sourceFile = 获取节点的源文件(nodeForSourceFile);
            如果 (!hasParseDiagnostics(sourceFile)) {
                diagnostics.添加(创建文件诊断信息(sourceFile, start, length, message, arg0, arg1, arg2));
                返回 为真;
            }
            返回 为假
        }

    }
}
